diff --git a/ccm-core/bin/ccm-hostinit b/ccm-core/bin/ccm-hostinit
index 437043729..4f2768695 100644
--- a/ccm-core/bin/ccm-hostinit
+++ b/ccm-core/bin/ccm-hostinit
@@ -14,36 +14,6 @@
# PATH, you have to adjust the paths.
CCM_LIB_DIR="../lib"
CCM_HOME_DIR="../.."
-# echo "CCM_LIB_DIR is " ${CCM_LIB_DIR}
-# echo "CCM_HOME_DIR is " ${CCM_HOME_DIR}
-
-# We need CATALINA_HOME environment variable to access Tomcat's lib dir.
-#if [[ -z "$CATALINA_HOME" ]] ; then
-# echo CATALINE_HOME not set. Guessing ...
-
-# if [ -f /etc/tomcat6/tomcat6.conf ]
-# then
-# . /etc/tomcat6/tomcat6.conf
-# echo
-# echo Using CATALINA_HOME = $CATALINA_HOME
-# echo If this doesn\'t work use
-# echo export CATALINA_HOME=/path/to/tomcat/installation
-# echo to point us to the correct location.
-# else
-# echo
-# echo ===================================================
-# echo Environment variable CATALINA_HOME not set. We need
-# echo to know the location of Tomcat\'s lib directory.
-# echo So use
-# echo export CATALINA_HOME=/path/to/tomcat/installation
-# echo to point us to the correct location and run ccm
-# echo again.
-# echo ===================================================
-# echo
-# exit 1
-# fi
-#fi
-#CATALINA_LIB_DIR="${CATALINA_HOME}/lib"
# We need CCM_REPO environment variable to access the source dir.
if [[ -z "$CCM_REPO" ]] ; then
@@ -73,7 +43,7 @@ if [[ -z "$CCM_REPO" ]] ; then
echo " export CCM_REPO=/path/to/repo "
echo to point us to the correct location and run
echo ccm-hostinit again or execute
- echo " CCM_REPO=/path/to/repo ccm-hostinit [task] "
+ echo " CCM_REPO=/path/to/repo sh ccm-hostinit [task] "
echo again
echo ===================================================
echo
@@ -97,26 +67,24 @@ then
exit 1
fi
-#if [ ! -f ${CATALINA_LIB_DIR}/catalina.jar ]
-#then
-# echo "Error: CATALINA_LIB_DIR is invalid \(no catalina.jar in CATALINA_LIB_DIR\)."
-# exit 1
-#fi
-
#Convert to absolute path:
CCM_HOME=`cd ${CCM_HOME_DIR}; pwd`
-# echo "CCM_HOME_DIR: " ${CCM_HOME_DIR}
-# echo "PARAMETER before shift: " "$@"
ANT_HOME_DIR="./libexec/ant"
ANT_HOME=`cd ${ANT_HOME_DIR}; pwd`
export ANT_HOME
-# echo "ANT_HOME: " ${ANT_HOME}
-# echo "Starting CCM-Tool..."
-# java -cp ${CCM_LIB_DIR}/"*":${CATALINA_LIB_DIR}/"*" -Dccm.home=${CCM_HOME_DIR} "com.arsdigita.packaging.MasterTool" "$@"
+
TASK="$1"
-# shift
shift
-# echo "PARAMETER after shift: " "$@"
-PACKAGES="$@" ${PACKAGES}
-# echo "Packages: " ${PACKAGES}
-exec libexec/ant/bin/ant ${TASK} -quiet -f libexec/build.xml -Dccm.home.dir=${CCM_HOME} -Dccm.repo.dir=${CCM_REPO} -Dccm.packages="${PACKAGES}"
+
+if [ "$1" = "--packagefile" ]
+ then
+ # Absolute path of current dir
+ MY_DIR=`pwd`
+ # Construct absolute (canonical) filename
+ FILENAME=${MY_DIR}/$2
+ exec libexec/ant/bin/ant ${TASK} -quiet -f libexec/build.xml -Dccm.home.dir=${CCM_HOME} -Dccm.repo.dir=${CCM_REPO} -Dccm.packages.filename="${FILENAME}"
+ else
+ PACKAGES="$@"
+ exec libexec/ant/bin/ant ${TASK} -quiet -f libexec/build.xml -Dccm.home.dir=${CCM_HOME} -Dccm.repo.dir=${CCM_REPO} -Dccm.packages="${PACKAGES}"
+fi
+
diff --git a/ccm-core/bin/libexec/ant/lib/dom4j.jar b/ccm-core/bin/libexec/ant/lib/dom4j.jar
new file mode 100644
index 000000000..c8c4dbb92
Binary files /dev/null and b/ccm-core/bin/libexec/ant/lib/dom4j.jar differ
diff --git a/ccm-core/bin/libexec/ant/lib/webxml-mergetool.jar b/ccm-core/bin/libexec/ant/lib/webxml-mergetool.jar
new file mode 100644
index 000000000..50b8c5e14
Binary files /dev/null and b/ccm-core/bin/libexec/ant/lib/webxml-mergetool.jar differ
diff --git a/ccm-core/bin/libexec/ant/lib/xerces.jar b/ccm-core/bin/libexec/ant/lib/xerces.jar
new file mode 100644
index 000000000..99ee39d5b
Binary files /dev/null and b/ccm-core/bin/libexec/ant/lib/xerces.jar differ
diff --git a/ccm-core/bin/libexec/build.xml b/ccm-core/bin/libexec/build.xml
index 7c1818250..82cfb04a5 100644
--- a/ccm-core/bin/libexec/build.xml
+++ b/ccm-core/bin/libexec/build.xml
@@ -22,7 +22,10 @@
HostInit deploys CCM into a servlet container. Specifically it deploys
ADDON packages.
-
+
+
@@ -44,59 +47,132 @@
-
+
- Packages requested: ${ccm.packages}
+
+
-
-
+
- Package working on: ${dirname}
+ Package working on: ${packagename}
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Installation of package ${packagename} completed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Info requested for Package(s):
- ${ccm.packages}
+ ${ccm.requested.packages}
@@ -105,9 +181,10 @@
-
+
@@ -120,9 +197,13 @@
+
+
+
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
Base directory is ${basedir}
diff --git a/ccm-core/bin/libexec/build.xml.bak b/ccm-core/bin/libexec/build.xml.bak
new file mode 100644
index 000000000..7c1818250
--- /dev/null
+++ b/ccm-core/bin/libexec/build.xml.bak
@@ -0,0 +1,157 @@
+
+
+
+
+
+ HostInit deploys CCM into a servlet container. Specifically it deploys
+ ADDON packages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Packages requested: ${ccm.packages}
+
+
+
+
+
+
+
+ Package working on: ${dirname}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Info requested for Package(s):
+ ${ccm.packages}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Base directory is ${basedir}
+ USAGE:
+ ccm-host list lists avaiblable addon packages
+ ccm-host add {packagelist} adds one or more packages to the aplaws application directory.
+ ccm-host info {package} displays info about a package.
+
+
+
+
diff --git a/tools-ng/common/webxml-mergetool/dist/README.TXT b/tools-ng/common/webxml-mergetool/dist/README.TXT
new file mode 100644
index 000000000..c75d5353e
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/dist/README.TXT
@@ -0,0 +1,32 @@
+========================
+BUILD OUTPUT DESCRIPTION
+========================
+
+When you build an Java application project that has a main class, the IDE
+automatically copies all of the JAR
+files on the projects classpath to your projects dist/lib folder. The IDE
+also adds each of the JAR files to the Class-Path element in the application
+JAR files manifest file (MANIFEST.MF).
+
+To run the project from the command line, go to the dist folder and
+type the following:
+
+java -jar "webxml-mergetool.jar"
+
+To distribute this project, zip up the dist folder (including the lib folder)
+and distribute the ZIP file.
+
+Notes:
+
+* If two JAR files on the project classpath have the same name, only the first
+JAR file is copied to the lib folder.
+* Only JAR files are copied to the lib folder.
+If the classpath contains other types of files or folders, these files (folders)
+are not copied.
+* If a library on the projects classpath also has a Class-Path element
+specified in the manifest,the content of the Class-Path element has to be on
+the projects runtime path.
+* To set a main class in a standard Java project, right-click the project node
+in the Projects window and choose Properties. Then click Run and enter the
+class name in the Main Class field. Alternatively, you can manually type the
+class name in the manifest Main-Class element.
diff --git a/tools-ng/common/webxml-mergetool/dist/lib/ant.jar b/tools-ng/common/webxml-mergetool/dist/lib/ant.jar
new file mode 100644
index 000000000..7f5be4a4e
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/dist/lib/ant.jar differ
diff --git a/tools-ng/common/webxml-mergetool/dist/lib/dom4j.jar b/tools-ng/common/webxml-mergetool/dist/lib/dom4j.jar
new file mode 100644
index 000000000..c8c4dbb92
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/dist/lib/dom4j.jar differ
diff --git a/tools-ng/common/webxml-mergetool/dist/lib/xerces.jar b/tools-ng/common/webxml-mergetool/dist/lib/xerces.jar
new file mode 100644
index 000000000..99ee39d5b
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/dist/lib/xerces.jar differ
diff --git a/tools-ng/common/webxml-mergetool/dist/webxml-mergetool.jar b/tools-ng/common/webxml-mergetool/dist/webxml-mergetool.jar
new file mode 100644
index 000000000..51ea9c2b5
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/dist/webxml-mergetool.jar differ
diff --git a/tools-ng/common/webxml-mergetool/howto-use.txt b/tools-ng/common/webxml-mergetool/howto-use.txt
new file mode 100644
index 000000000..4db0cff70
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/howto-use.txt
@@ -0,0 +1,34 @@
+webxml-mergetool
+
+Purpose:
+
+Takes an existing web.xml deployment descriptor (original file) and
+a web.xml fragment (merge file) and inserts those elements of merge file
+which are not already in original file into original file and save the
+combined content in destination file.
+
+Usage:
+
+The tool acts as an ANT task.
+
+At beginning of build.xml:
+
+
+
+To use add at appropriate location:
+
+
+
+
+
+Eventually followed by
+
+
+
+
diff --git a/tools-ng/common/webxml-mergetool/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar b/tools-ng/common/webxml-mergetool/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar
new file mode 100644
index 000000000..1c0f59737
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/ant.jar b/tools-ng/common/webxml-mergetool/lib/ant.jar
new file mode 100644
index 000000000..7f5be4a4e
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/ant.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/chardet.jar b/tools-ng/common/webxml-mergetool/lib/chardet.jar
new file mode 100644
index 000000000..a46d26f57
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/chardet.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/dom4j.jar b/tools-ng/common/webxml-mergetool/lib/dom4j.jar
new file mode 100644
index 000000000..c8c4dbb92
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/dom4j.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/jackrabbit-text-extractors.jar b/tools-ng/common/webxml-mergetool/lib/jackrabbit-text-extractors.jar
new file mode 100644
index 000000000..df369080f
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/jackrabbit-text-extractors.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/jericho-html.jar b/tools-ng/common/webxml-mergetool/lib/jericho-html.jar
new file mode 100644
index 000000000..97c06ee12
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/jericho-html.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/nblibraries.properties b/tools-ng/common/webxml-mergetool/lib/nblibraries.properties
new file mode 100644
index 000000000..03b52d682
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/lib/nblibraries.properties
@@ -0,0 +1,2 @@
+libs.CopyLibs.classpath=\
+ ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar
diff --git a/tools-ng/common/webxml-mergetool/lib/poi-ooxml.jar b/tools-ng/common/webxml-mergetool/lib/poi-ooxml.jar
new file mode 100644
index 000000000..c986646e6
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/poi-ooxml.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/poi.jar b/tools-ng/common/webxml-mergetool/lib/poi.jar
new file mode 100644
index 000000000..9972d9732
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/poi.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/tomcat5-jsp-2.0-api-5.5.27.jar b/tools-ng/common/webxml-mergetool/lib/tomcat5-jsp-2.0-api-5.5.27.jar
new file mode 100644
index 000000000..a9b6f5596
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/tomcat5-jsp-2.0-api-5.5.27.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/tomcat5-servlet-2.4-api-5.5.27.jar b/tools-ng/common/webxml-mergetool/lib/tomcat5-servlet-2.4-api-5.5.27.jar
new file mode 100644
index 000000000..012998c38
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/tomcat5-servlet-2.4-api-5.5.27.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/xbean.jar b/tools-ng/common/webxml-mergetool/lib/xbean.jar
new file mode 100644
index 000000000..9983d7226
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/xbean.jar differ
diff --git a/tools-ng/common/webxml-mergetool/lib/xerces.jar b/tools-ng/common/webxml-mergetool/lib/xerces.jar
new file mode 100644
index 000000000..99ee39d5b
Binary files /dev/null and b/tools-ng/common/webxml-mergetool/lib/xerces.jar differ
diff --git a/tools-ng/common/webxml-mergetool/manifest.mf b/tools-ng/common/webxml-mergetool/manifest.mf
new file mode 100644
index 000000000..328e8e5bc
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/manifest.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+
diff --git a/tools-ng/common/webxml-mergetool/nbbuild.xml b/tools-ng/common/webxml-mergetool/nbbuild.xml
new file mode 100644
index 000000000..1ef09d9fc
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/nbbuild.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+ Builds, tests, and runs the project webxml-mergetool.
+
+
+
diff --git a/tools-ng/common/webxml-mergetool/src/com/arsdigita/ant/WebXMLMergeTask.java b/tools-ng/common/webxml-mergetool/src/com/arsdigita/ant/WebXMLMergeTask.java
new file mode 100644
index 000000000..20f795d3a
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/arsdigita/ant/WebXMLMergeTask.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2011 Peter Boy (pb@zes.uni-bremen.de) All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.arsdigita.ant;
+
+
+import com.liferay.portal.kernel.util.GetterUtil;
+import com.liferay.portal.kernel.util.StringUtil;
+import com.liferay.portal.kernel.xml.Document;
+import com.liferay.portal.kernel.xml.DocumentException;
+import com.liferay.portal.kernel.xml.Element;
+import com.liferay.portal.kernel.xml.SAXReaderUtil;
+import com.liferay.portal.xml.DocumentImpl;
+import com.liferay.portal.xml.SAXReaderImpl;
+import com.liferay.util.xml.XMLMerger;
+import com.liferay.util.xml.descriptor.WebXML23Descriptor;
+import com.liferay.util.xml.descriptor.WebXML24Descriptor;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+// import org.apache.tools.ant.Project;
+
+
+
+/**
+ *
+ * @author pb
+ */
+public class WebXMLMergeTask extends Task {
+
+ // Instance Variables ------------------------------------------------------
+
+ /** Location of the original web.xml. */
+ private String originalFile;
+
+ /** Location of the file to merge in web.xml. */
+ private String mergeFile;
+
+ /** Location of the resulting (destination) web.xml. */
+ private String destFile;
+
+ // Public Methods ----------------------------------------------------------
+
+ /**
+ * {@inheritDoc}
+ * @see Task#execute()
+ */
+ @Override
+ public void execute() throws BuildException {
+
+// /* Check parameters */
+// if ((this.originalFile == null) || !this.originalFile.isFile())
+// {
+// throw new BuildException("The [originalfile] attribute is required");
+// }
+// if (this.mergeFile == null)
+// {
+// throw new BuildException("The [mergefile] attribute is required");
+// }
+// if (this.destFile == null)
+// {
+// throw new BuildException("The [destfile] attribute is required");
+// }
+
+ BuildWebXML(originalFile, mergeFile, destFile);
+
+
+ }
+
+ private void BuildWebXML(String originalWebXML, String customWebXML,
+ String mergedWebXML) {
+
+ try {
+
+ String customContent = readFileIntoString(customWebXML);
+
+ int x = customContent.indexOf("", x) + 1;
+ int y = customContent.indexOf("");
+ customContent = customContent.substring(x, y);
+
+
+ String originalContent = readFileIntoString(originalWebXML);
+
+ int z = originalContent.indexOf("", z) + 1;
+
+
+ String mergedContent =
+ originalContent.substring(0, z) + customContent +
+ originalContent.substring(z, originalContent.length());
+
+ mergedContent = processContent(mergedContent);
+
+
+ writeFileFromString(mergedWebXML, mergedContent);
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private String processContent(String webXML)
+ throws DocumentException, IOException {
+
+ webXML = stripHtmlComments(webXML);
+ new SAXReaderUtil().setSAXReader(new SAXReaderImpl());
+
+ double version = 2.3;
+
+ Document doc = SAXReaderUtil.read(webXML);
+
+ Element root = doc.getRootElement();
+
+ version = GetterUtil.getDouble(root.attributeValue("version"), version);
+
+ XMLMerger merger = null;
+
+ if (version == 2.3) {
+ merger = new XMLMerger(new WebXML23Descriptor());
+ }
+ else {
+ merger = new XMLMerger(new WebXML24Descriptor());
+ }
+
+ DocumentImpl docImpl = (DocumentImpl)doc;
+
+ merger.organizeXML(docImpl.getWrappedDocument());
+
+ webXML = doc.formattedString();
+
+ return webXML;
+
+ }
+
+ private String readFileIntoString(String filename)
+ throws IOException {
+
+ BufferedReader cbr = new BufferedReader(
+ new InputStreamReader(
+ new FileInputStream(filename)));
+ StringBuilder contentOfFile = new StringBuilder();
+ String line;
+ while ((line = cbr.readLine()) != null) {
+ contentOfFile.append(line);
+ contentOfFile.append('\n');
+ }
+
+ return(contentOfFile.toString());
+ }
+
+ private void writeFileFromString(String fileName, String content)
+ throws IOException{
+
+ FileOutputStream fos = new FileOutputStream(fileName);
+ for (int i=0; i < content.length(); i++){
+ fos.write((byte)content.charAt(i));
+ }
+ fos.close();
+
+ }
+
+ private String stripHtmlComments(String xmlContent) {
+
+ String strippedContent = StringUtil.stripBetween(xmlContent,
+ "");
+ return(strippedContent);
+ }
+
+ /**
+ * The original web deployment descriptor into which the new elements will
+ * be merged.
+ *
+ * @param theSrcFile the original web.xml
+ */
+ public final void setOriginalFile(String originalFile)
+ {
+ this.originalFile = originalFile;
+ }
+
+ /**
+ * The descriptor to merge into the original file.
+ *
+ * @param theMergeFile the web.xml to merge
+ */
+ public final void setMergeFile(String mergeFile)
+ {
+ this.mergeFile = mergeFile;
+ }
+
+ /**
+ * The destination file where the result of the merge are stored.
+ *
+ * @param theDestFile the resulting web.xml
+ */
+ public final void setDestFile(String destFile)
+ {
+ this.destFile = destFile;
+ }
+
+
+
+}
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncBufferedReader.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncBufferedReader.java
new file mode 100644
index 000000000..6225f7e11
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncBufferedReader.java
@@ -0,0 +1,378 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.io.unsync;
+
+import com.liferay.portal.kernel.util.CharPool;
+import com.liferay.portal.kernel.util.StringBundler;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ *
+ * See http://issues.liferay.com/browse/LPS-6648.
+ *
+ *
+ * @author Shuyang Zhou
+ */
+public class UnsyncBufferedReader extends Reader {
+
+ public UnsyncBufferedReader(Reader reader) {
+ this(reader, _DEFAULT_BUFFER_SIZE);
+ }
+
+ public UnsyncBufferedReader(Reader reader, int size) {
+ this.reader = reader;
+ buffer = new char[size];
+ }
+
+ public void close() throws IOException {
+ if (reader != null) {
+ reader.close();
+
+ reader = null;
+ }
+
+ buffer = null;
+ }
+
+ public void mark(int markLimit) throws IOException {
+ if (reader == null) {
+ throw new IOException("Reader is null");
+ }
+
+ this.markLimit = markLimit;
+ markIndex = index;
+ }
+
+ public boolean markSupported() {
+ return true;
+ }
+
+ public int read() throws IOException {
+ if (reader == null) {
+ throw new IOException("Reader is null");
+ }
+
+ if (index >= firstInvalidIndex) {
+ readUnderlyingReader();
+
+ if (index >= firstInvalidIndex) {
+ return -1;
+ }
+ }
+
+ return buffer[index++];
+ }
+
+ public int read(char[] charArray) throws IOException {
+ return read(charArray, 0, charArray.length);
+ }
+
+ public int read(char[] charArray, int offset, int length)
+ throws IOException {
+
+ if (reader == null) {
+ throw new IOException("Reader is null");
+ }
+
+ if (length <= 0) {
+ return 0;
+ }
+
+ int read = 0;
+
+ while (true) {
+ int available = firstInvalidIndex - index;
+
+ if ((available + read) >= length) {
+
+ // Enough data, stop reading
+
+ int leftSize = length - read;
+
+ System.arraycopy(buffer, index, charArray, read, leftSize);
+
+ index += leftSize;
+
+ return length;
+ }
+
+ if (available <= 0) {
+
+ // No more data in buffer, continue reading
+
+ readUnderlyingReader();
+
+ available = firstInvalidIndex - index;
+
+ if (available <= 0) {
+
+ // Cannot read any more, stop reading
+
+ if (read == 0) {
+ return -1;
+ }
+ else {
+ return read;
+ }
+ }
+ }
+ else {
+
+ // Copy all in-memory data, continue reading
+
+ System.arraycopy(buffer, index, charArray, read, available);
+
+ index += available;
+ read += available;
+ }
+ }
+ }
+
+ public String readLine() throws IOException {
+ if (reader == null) {
+ throw new IOException("Reader is null");
+ }
+
+ StringBundler sb = null;
+
+ while (true) {
+ if (index >= firstInvalidIndex) {
+ readUnderlyingReader();
+ }
+
+ if (index >= firstInvalidIndex) {
+ if ((sb != null) && (sb.index() > 0)) {
+ return sb.toString();
+ }
+ else {
+ return null;
+ }
+ }
+
+ boolean hasLineBreak = false;
+ char lineEndChar = 0;
+
+ int x = index;
+ int y = index;
+
+ while (y < firstInvalidIndex) {
+ lineEndChar = buffer[y];
+
+ if ((lineEndChar == CharPool.NEW_LINE) ||
+ (lineEndChar == CharPool.RETURN)) {
+
+ hasLineBreak = true;
+
+ break;
+ }
+
+ y++;
+ }
+
+ String line = new String(buffer, x, y - x);
+
+ index = y;
+
+ if (hasLineBreak) {
+ index++;
+
+ if (lineEndChar == CharPool.RETURN) {
+ if ((index < buffer.length) &&
+ (buffer[index] == CharPool.NEW_LINE)) {
+
+ index++;
+ }
+ }
+
+ if (sb == null) {
+ return line;
+ }
+ else {
+ sb.append(line);
+
+ return sb.toString();
+ }
+ }
+
+ if (sb == null) {
+ sb = new StringBundler();
+ }
+
+ sb.append(line);
+ }
+ }
+
+ public boolean ready() throws IOException {
+ if (reader == null) {
+ throw new IOException("Reader is null");
+ }
+
+ return (index < firstInvalidIndex) || reader.ready();
+ }
+
+ public void reset() throws IOException {
+ if (reader == null) {
+ throw new IOException("Reader is null");
+ }
+
+ if (markIndex < 0) {
+ throw new IOException("Resetting to invalid mark");
+ }
+
+ index = markIndex;
+ }
+
+ public long skip(long skip) throws IOException {
+ if (reader == null) {
+ throw new IOException("Reader is null");
+ }
+
+ if (skip <= 0) {
+ return 0;
+ }
+
+ long available = firstInvalidIndex - index;
+
+ if (available > 0) {
+
+ // Skip the data in buffer
+
+ if (available < skip) {
+ skip = available;
+ }
+ }
+ else {
+
+ // Skip the underlying reader
+
+ if (markIndex < 0) {
+
+ // No mark required, skip
+
+ skip = reader.skip(skip);
+ }
+ else {
+
+ // Mark required, save the skipped data
+
+ readUnderlyingReader();
+
+ available = firstInvalidIndex - index;
+
+ if (available > 0) {
+
+ // Skip the data in buffer
+
+ if (available < skip) {
+ skip = available;
+ }
+ }
+ }
+ }
+
+ index += skip;
+
+ return skip;
+ }
+
+ protected void readUnderlyingReader() throws IOException {
+ if (markIndex < 0) {
+
+ // No mark required, fill the buffer
+
+ index = firstInvalidIndex = 0;
+
+ int number = reader.read(buffer);
+
+ if (number > 0) {
+ firstInvalidIndex = number;
+ }
+
+ return;
+ }
+
+ // Mark required
+
+ if (index >= buffer.length) {
+
+ // Buffer is full, clean up or grow
+
+ if ((firstInvalidIndex - markIndex) > markLimit) {
+
+ // Passed mark limit, get rid of all cache data
+
+ markIndex = -1;
+ index = 0;
+ }
+ else if (markIndex > _MAX_MARK_WASTE_SIZE) {
+
+ // There are more than _MAX_MARK_WASTE_SIZE free space at the
+ // beginning of buffer, clean up by shuffling the buffer
+
+ int realDataSize = index - markIndex;
+
+ System.arraycopy(
+ buffer, markIndex, buffer, 0, realDataSize);
+
+ markIndex = 0;
+ index = realDataSize;
+ }
+ else {
+
+ // Grow the buffer because we cannot get rid of cache data and
+ // it is inefficient to shuffle the buffer
+
+ int newBufferSize = index << 1;
+
+ if ((newBufferSize - _MAX_MARK_WASTE_SIZE) > markLimit) {
+
+ // Make thew new buffer size larger than the mark limit
+
+ newBufferSize = markLimit + _MAX_MARK_WASTE_SIZE;
+ }
+
+ char[] newBuffer = new char[newBufferSize];
+
+ System.arraycopy(buffer, 0, newBuffer, 0, index);
+
+ buffer = newBuffer;
+ }
+ }
+
+ // Read underlying reader since the buffer has more space
+
+ firstInvalidIndex = index;
+
+ int number = reader.read(buffer, index, buffer.length - index);
+
+ if (number > 0) {
+ firstInvalidIndex += number;
+ }
+ }
+
+ protected char[] buffer;
+ protected int firstInvalidIndex;
+ protected int index;
+ protected int markIndex = -1;
+ protected int markLimit;
+ protected Reader reader;
+
+ private static int _DEFAULT_BUFFER_SIZE = 8192;
+
+ private static int _MAX_MARK_WASTE_SIZE = 4096;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncByteArrayInputStream.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncByteArrayInputStream.java
new file mode 100644
index 000000000..73847ea29
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncByteArrayInputStream.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.io.unsync;
+
+import java.io.InputStream;
+
+/**
+ *
+ * See http://issues.liferay.com/browse/LPS-6648.
+ *
+ *
+ * @author Shuyang Zhou
+ */
+public class UnsyncByteArrayInputStream extends InputStream {
+
+ public UnsyncByteArrayInputStream(byte[] buffer) {
+ this.buffer = buffer;
+ this.index = 0;
+ this.capacity = buffer.length;
+ }
+
+ public UnsyncByteArrayInputStream(byte[] buffer, int offset, int length) {
+ this.buffer = buffer;
+ this.index = offset;
+ this.capacity = Math.min(buffer.length, offset + length);
+ this.markIndex = offset;
+ }
+
+ public int available() {
+ return capacity - index;
+ }
+
+ public void mark(int readAheadLimit) {
+ markIndex = index;
+ }
+
+ public boolean markSupported() {
+ return true;
+ }
+
+ public int read() {
+ if (index < capacity) {
+ return buffer[index++] & 0xff;
+ }
+ else {
+ return -1;
+ }
+ }
+
+ public int read(byte[] byteArray) {
+ return read(byteArray, 0, byteArray.length);
+ }
+
+ public int read(byte[] byteArray, int offset, int length) {
+ if (length <= 0) {
+ return 0;
+ }
+
+ if (index >= capacity) {
+ return -1;
+ }
+
+ int read = length;
+
+ if ((index + read) > capacity) {
+ read = capacity - index;
+ }
+
+ System.arraycopy(buffer, index, byteArray, offset, read);
+
+ index += read;
+
+ return read;
+ }
+
+ public void reset() {
+ index = markIndex;
+ }
+
+ public long skip(long skip) {
+ if (skip < 0) {
+ return 0;
+ }
+
+ if ((skip + index) > capacity) {
+ skip = capacity - index;
+ }
+
+ index += skip;
+
+ return skip;
+ }
+
+ protected byte[] buffer;
+ protected int capacity;
+ protected int index;
+ protected int markIndex;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncByteArrayOutputStream.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncByteArrayOutputStream.java
new file mode 100644
index 000000000..4e1c13efe
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncByteArrayOutputStream.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.io.unsync;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import java.nio.ByteBuffer;
+
+/**
+ *
+ * See http://issues.liferay.com/browse/LPS-6648.
+ *
+ *
+ * @author Shuyang Zhou
+ */
+public class UnsyncByteArrayOutputStream extends OutputStream {
+
+ public UnsyncByteArrayOutputStream() {
+ this(32);
+ }
+
+ public UnsyncByteArrayOutputStream(int size) {
+ buffer = new byte[size];
+ }
+
+ public void reset() {
+ index = 0;
+ }
+
+ public int size() {
+ return index;
+ }
+
+ public byte[] toByteArray() {
+ byte[] newBuffer = new byte[index];
+
+ System.arraycopy(buffer, 0, newBuffer, 0, index);
+
+ return newBuffer;
+ }
+
+ public String toString() {
+ return new String(buffer, 0, index);
+ }
+
+ public String toString(String charsetName)
+ throws UnsupportedEncodingException {
+
+ return new String(buffer, 0, index, charsetName);
+ }
+
+ public byte[] unsafeGetByteArray() {
+ return buffer;
+ }
+
+ public ByteBuffer unsafeGetByteBuffer() {
+ return ByteBuffer.wrap(buffer, 0, index);
+ }
+
+ public void write(byte[] byteArray) {
+ write(byteArray, 0, byteArray.length);
+ }
+
+ public void write(byte[] byteArray, int offset, int length) {
+ if (length <= 0) {
+ return;
+ }
+
+ int newIndex = index + length;
+
+ if (newIndex > buffer.length) {
+ int newBufferSize = Math.max(buffer.length << 1, newIndex);
+
+ byte[] newBuffer = new byte[newBufferSize];
+
+ System.arraycopy(buffer, 0, newBuffer, 0, index);
+
+ buffer = newBuffer;
+ }
+
+ System.arraycopy(byteArray, offset, buffer, index, length);
+
+ index = newIndex;
+ }
+
+ public void write(int b) {
+ int newIndex = index + 1;
+
+ if (newIndex > buffer.length) {
+ int newBufferSize = Math.max(buffer.length << 1, newIndex);
+
+ byte[] newBuffer = new byte[newBufferSize];
+
+ System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
+
+ buffer = newBuffer;
+ }
+
+ buffer[index] = (byte)b;
+
+ index = newIndex;
+ }
+
+ public void writeTo(OutputStream outputStream) throws IOException {
+ outputStream.write(buffer, 0, index);
+ }
+
+ protected byte[] buffer;
+ protected int index;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncPrintWriter.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncPrintWriter.java
new file mode 100644
index 000000000..2bb7cf90a
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncPrintWriter.java
@@ -0,0 +1,393 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.io.unsync;
+
+import com.liferay.portal.kernel.util.StringPool;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+
+import java.util.Formatter;
+import java.util.Locale;
+
+/**
+ *
+ * See http://issues.liferay.com/browse/LPS-6648.
+ *
+ *
+ * @author Shuyang Zhou
+ */
+public class UnsyncPrintWriter extends PrintWriter {
+
+ public UnsyncPrintWriter(File file) throws IOException {
+ this(new FileWriter(file), false);
+ }
+
+ public UnsyncPrintWriter(File file, String csn)
+ throws FileNotFoundException, UnsupportedEncodingException {
+
+ this(new OutputStreamWriter(new FileOutputStream(file), csn), false);
+ }
+
+ public UnsyncPrintWriter(OutputStream outputStream) {
+ this(outputStream, false);
+ }
+
+ public UnsyncPrintWriter(OutputStream outputStream, boolean autoFlush) {
+ this(new OutputStreamWriter(outputStream), autoFlush);
+ }
+
+ public UnsyncPrintWriter(String fileName) throws IOException {
+ this(new FileWriter(fileName), false);
+ }
+
+ public UnsyncPrintWriter(String fileName, String csn)
+ throws FileNotFoundException, UnsupportedEncodingException {
+
+ this(
+ new OutputStreamWriter(new FileOutputStream(fileName), csn), false);
+ }
+
+ public UnsyncPrintWriter(Writer writer) {
+ this(writer, false);
+ }
+
+ public UnsyncPrintWriter(Writer writer, boolean autoFlush) {
+ super(writer);
+
+ _writer = writer;
+ _autoFlush = autoFlush;
+ }
+
+ public PrintWriter append(char c) {
+ write(c);
+
+ return this;
+ }
+
+ public PrintWriter append(CharSequence charSequence) {
+ if (charSequence == null) {
+ write(StringPool.NULL);
+ }
+ else {
+ write(charSequence.toString());
+ }
+
+ return this;
+ }
+
+ public PrintWriter append(CharSequence charSequence, int start, int end) {
+ if (charSequence == null) {
+ charSequence = StringPool.NULL;
+ }
+
+ write(charSequence.subSequence(start, end).toString());
+
+ return this;
+ }
+
+ public boolean checkError() {
+ if (_writer != null) {
+ flush();
+ }
+
+ return _hasError;
+ }
+
+ public void close() {
+ try {
+ if (_writer == null) {
+ return;
+ }
+
+ _writer.close();
+
+ _writer = null;
+ }
+ catch (IOException ioe) {
+ _hasError = true;
+ }
+ }
+
+ public void flush() {
+ if (_writer == null) {
+ _hasError = true;
+ }
+ else {
+ try {
+ _writer.flush();
+ }
+ catch (IOException ioe) {
+ _hasError = true;
+ }
+ }
+ }
+
+ public PrintWriter format(
+ Locale locale, String format, Object... arguments) {
+
+ if (_writer == null) {
+ _hasError = true;
+ }
+ else {
+ try {
+ if ((_formatter == null) || (_formatter.locale() != locale)) {
+ _formatter = new Formatter(this, locale);
+ }
+
+ _formatter.format(locale, format, arguments);
+
+ if (_autoFlush) {
+ _writer.flush();
+ }
+ }
+ catch (InterruptedIOException iioe) {
+ Thread currentThread = Thread.currentThread();
+
+ currentThread.interrupt();
+ }
+ catch (IOException ioe) {
+ _hasError = true;
+ }
+ }
+
+ return this;
+ }
+
+ public PrintWriter format(String format, Object... arguments) {
+ return format(Locale.getDefault(), format, arguments);
+ }
+
+ public void print(boolean b) {
+ if (b) {
+ write(StringPool.TRUE);
+ }
+ else {
+ write(StringPool.FALSE);
+ }
+ }
+
+ public void print(char c) {
+ write(c);
+ }
+
+ public void print(char[] charArray) {
+ write(charArray);
+ }
+
+ public void print(double d) {
+ write(String.valueOf(d));
+ }
+
+ public void print(float f) {
+ write(String.valueOf(f));
+ }
+
+ public void print(int i) {
+ write(String.valueOf(i));
+ }
+
+ public void print(long l) {
+ write(String.valueOf(l));
+ }
+
+ public void print(Object object) {
+ write(String.valueOf(object));
+ }
+
+ public void print(String string) {
+ if (string == null) {
+ string = StringPool.NULL;
+ }
+
+ write(string);
+ }
+
+ public PrintWriter printf(
+ Locale locale, String format, Object... arguments) {
+
+ return format(locale, format, arguments);
+ }
+
+ public PrintWriter printf(String format, Object... arguments) {
+ return format(format, arguments);
+ }
+
+ public void println() {
+ if (_writer == null) {
+ _hasError = true;
+ }
+ else {
+ try {
+ _writer.write(_LINE_SEPARATOR);
+
+ if (_autoFlush) {
+ _writer.flush();
+ }
+ }
+ catch (InterruptedIOException iioe) {
+ Thread currentThread = Thread.currentThread();
+
+ currentThread.interrupt();
+ }
+ catch (IOException ioe) {
+ _hasError = true;
+ }
+ }
+ }
+
+ public void println(boolean b) {
+ print(b);
+ println();
+ }
+
+ public void println(char c) {
+ print(c);
+ println();
+ }
+
+ public void println(char[] charArray) {
+ print(charArray);
+ println();
+ }
+
+ public void println(double d) {
+ print(d);
+ println();
+ }
+
+ public void println(float f) {
+ print(f);
+ println();
+ }
+
+ public void println(int i) {
+ print(i);
+ println();
+ }
+
+ public void println(long l) {
+ print(l);
+ println();
+ }
+
+ public void println(Object object) {
+ print(object);
+ println();
+ }
+
+ public void println(String string) {
+ print(string);
+ println();
+ }
+
+ public void write(char[] charArray) {
+ write(charArray, 0, charArray.length);
+ }
+
+ public void write(char[] charArray, int offset, int length) {
+ if (_writer == null) {
+ _hasError = true;
+ }
+ else {
+ try {
+ _writer.write(charArray, offset, length);
+ }
+ catch (InterruptedIOException iioe) {
+ Thread currentThread = Thread.currentThread();
+
+ currentThread.interrupt();
+ }
+ catch (IOException ioe) {
+ _hasError = true;
+ }
+ }
+ }
+
+ public void write(int c) {
+ if (_writer == null) {
+ _hasError = true;
+ }
+ else {
+ try {
+ _writer.write(c);
+ }
+ catch (InterruptedIOException iioe) {
+ Thread currentThread = Thread.currentThread();
+
+ currentThread.interrupt();
+ }
+ catch (IOException ioe) {
+ _hasError = true;
+ }
+ }
+ }
+
+ public void write(String string) {
+ if (_writer == null) {
+ _hasError = true;
+ }
+ else {
+ try {
+ _writer.write(string);
+ }
+ catch (InterruptedIOException iioe) {
+ Thread currentThread = Thread.currentThread();
+
+ currentThread.interrupt();
+ }
+ catch (IOException ioe) {
+ _hasError = true;
+ }
+ }
+ }
+
+ public void write(String string, int offset, int length) {
+ if (_writer == null) {
+ _hasError = true;
+ }
+ else {
+ try {
+ _writer.write(string, offset, length);
+ }
+ catch (InterruptedIOException iioe) {
+ Thread currentThread = Thread.currentThread();
+
+ currentThread.interrupt();
+ }
+ catch (IOException ioe) {
+ _hasError = true;
+ }
+ }
+ }
+
+ private static String _LINE_SEPARATOR = System.getProperty(
+ "line.separator");
+
+ private boolean _autoFlush;
+ private Formatter _formatter;
+ private boolean _hasError;
+ private Writer _writer;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncStringReader.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncStringReader.java
new file mode 100644
index 000000000..e3000eacd
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncStringReader.java
@@ -0,0 +1,144 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.io.unsync;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import java.nio.CharBuffer;
+
+/**
+ *
+ * See http://issues.liferay.com/browse/LPS-6648.
+ *
+ *
+ * @author Shuyang Zhou
+ */
+public class UnsyncStringReader extends Reader {
+
+ public UnsyncStringReader(String string) {
+ this.string = string;
+ stringLength = string.length();
+ }
+
+ public void close() {
+ string = null;
+ }
+
+ public void mark(int readAheadLimit) throws IOException {
+ if (string == null) {
+ throw new IOException("String is null");
+ }
+ markIndex = index;
+ }
+
+ public boolean markSupported() {
+ return true;
+ }
+
+ public int read() throws IOException {
+ if (string == null) {
+ throw new IOException("String is null");
+ }
+
+ if (index >= stringLength) {
+ return -1;
+ }
+
+ return string.charAt(index++);
+ }
+
+ public int read(char[] charArray) throws IOException {
+ return read(charArray, 0, charArray.length);
+ }
+
+ public int read(char[] charArray, int offset, int length)
+ throws IOException {
+
+ if (string == null) {
+ throw new IOException("String is null");
+ }
+
+ if (length <= 0) {
+ return 0;
+ }
+
+ if (index >= stringLength) {
+ return -1;
+ }
+
+ int read = length;
+
+ if ((index + read) > stringLength) {
+ read = stringLength - index;
+ }
+
+ string.getChars(index, index + read, charArray, offset);
+
+ index += read;
+
+ return read;
+ }
+
+ public int read(CharBuffer charBuffer) throws IOException {
+ int remaining = charBuffer.remaining();
+
+ char[] charArray = new char[remaining];
+
+ int read = read(charArray, 0, remaining);
+
+ if (read > 0) {
+ charBuffer.put(charArray, 0, read);
+ }
+
+ return read;
+ }
+
+ public boolean ready() throws IOException {
+ if (string == null) {
+ throw new IOException("String is null");
+ }
+
+ return true;
+ }
+
+ public void reset() throws IOException {
+ if (string == null) {
+ throw new IOException("String is null");
+ }
+
+ index = markIndex;
+ }
+
+ public long skip(long skip) {
+ if (index >= stringLength) {
+ return 0;
+ }
+
+ if ((skip + index) > stringLength) {
+ skip = stringLength - index;
+ }
+
+ index += skip;
+
+ return skip;
+ }
+
+ protected int index;
+ protected int stringLength;
+ protected int markIndex;
+ protected String string;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncStringWriter.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncStringWriter.java
new file mode 100644
index 000000000..8ddd6def0
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/io/unsync/UnsyncStringWriter.java
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.io.unsync;
+
+import com.liferay.portal.kernel.util.StringBundler;
+import com.liferay.portal.kernel.util.StringPool;
+
+import java.io.Writer;
+
+/**
+ *
+ * See http://issues.liferay.com/browse/LPS-6648.
+ *
+ *
+ * @author Shuyang Zhou
+ */
+public class UnsyncStringWriter extends Writer {
+
+ public UnsyncStringWriter() {
+ this(true);
+ }
+
+ public UnsyncStringWriter(boolean useStringBundler) {
+ if (useStringBundler) {
+ stringBundler = new StringBundler();
+ }
+ else {
+ stringBuilder = new StringBuilder();
+ }
+ }
+
+ public UnsyncStringWriter(boolean useStringBundler, int initialCapacity) {
+ if (useStringBundler) {
+ stringBundler = new StringBundler(initialCapacity);
+ }
+ else {
+ stringBuilder = new StringBuilder(initialCapacity);
+ }
+ }
+
+ public UnsyncStringWriter(int initialCapacity) {
+ this(true, initialCapacity);
+ }
+
+ public UnsyncStringWriter append(char c) {
+ write(c);
+
+ return this;
+ }
+
+ public UnsyncStringWriter append(CharSequence charSequence) {
+ if (charSequence == null) {
+ write(StringPool.NULL);
+ }
+ else {
+ write(charSequence.toString());
+ }
+
+ return this;
+ }
+
+ public UnsyncStringWriter append(
+ CharSequence charSequence, int start, int end) {
+
+ if (charSequence == null) {
+ charSequence = StringPool.NULL;
+ }
+
+ write(charSequence.subSequence(start, end).toString());
+
+ return this;
+ }
+
+ public void close() {
+ }
+
+ public void flush() {
+ }
+
+ public StringBuilder getStringBuilder() {
+ return stringBuilder;
+ }
+
+ public StringBundler getStringBundler() {
+ return stringBundler;
+ }
+
+ public void reset() {
+ if (stringBundler != null) {
+ stringBundler.setIndex(0);
+ }
+ else {
+ stringBuilder.setLength(0);
+ }
+ }
+
+ public String toString() {
+ if (stringBundler != null) {
+ return stringBundler.toString();
+ }
+ else {
+ return stringBuilder.toString();
+ }
+ }
+
+ public void write(char[] charArray, int offset, int length) {
+ if (length <= 0) {
+ return;
+ }
+
+ if (stringBundler != null) {
+ stringBundler.append(new String(charArray, offset, length));
+ }
+ else {
+ stringBuilder.append(charArray, offset, length);
+ }
+ }
+
+ public void write(char[] charArray) {
+ write(charArray, 0, charArray.length);
+
+ }
+
+ public void write(int c) {
+ if (stringBundler != null) {
+ stringBundler.append(String.valueOf((char)c));
+ }
+ else {
+ stringBuilder.append((char)c);
+ }
+ }
+
+ public void write(String string) {
+ if (stringBundler != null) {
+ stringBundler.append(string);
+ }
+ else {
+ stringBuilder.append(string);
+ }
+ }
+
+ public void write(String string, int offset, int length) {
+ if (stringBundler != null) {
+ stringBundler.append(string.substring(offset, offset + length));
+ }
+ else {
+ stringBuilder.append(string.substring(offset, offset + length));
+ }
+ }
+
+ protected StringBuilder stringBuilder;
+ protected StringBundler stringBundler;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Jdk14LogFactoryImpl.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Jdk14LogFactoryImpl.java
new file mode 100644
index 000000000..c92a072eb
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Jdk14LogFactoryImpl.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.log;
+
+import java.util.logging.Logger;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class Jdk14LogFactoryImpl implements LogFactory {
+
+ public Log getLog(Class> c) {
+ return getLog(c.getName());
+ }
+
+ public Log getLog(String name) {
+ return new Jdk14LogImpl(Logger.getLogger(name));
+ }
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Jdk14LogImpl.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Jdk14LogImpl.java
new file mode 100644
index 000000000..81fc171c0
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Jdk14LogImpl.java
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.log;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class Jdk14LogImpl implements Log {
+
+ public Jdk14LogImpl(Logger log) {
+ _log = log;
+ }
+
+ public void debug(Object msg) {
+ _log.log(Level.FINE, msg.toString());
+ }
+
+ public void debug(Throwable t) {
+ _log.log(Level.FINE, t.getMessage(), t);
+ }
+
+ public void debug(Object msg, Throwable t) {
+ _log.log(Level.FINE, msg.toString(), t);
+ }
+
+ public void error(Object msg) {
+ _log.log(Level.SEVERE, msg.toString());
+ }
+
+ public void error(Throwable t) {
+ _log.log(Level.SEVERE, t.getMessage(), t);
+ }
+
+ public void error(Object msg, Throwable t) {
+ _log.log(Level.SEVERE, msg.toString(), t);
+ }
+
+ public void fatal(Object msg) {
+ _log.log(Level.SEVERE, msg.toString());
+ }
+
+ public void fatal(Throwable t) {
+ _log.log(Level.SEVERE, t.getMessage(), t);
+ }
+
+ public void fatal(Object msg, Throwable t) {
+ _log.log(Level.SEVERE, msg.toString(), t);
+ }
+
+ public void info(Object msg) {
+ _log.log(Level.INFO, msg.toString());
+ }
+
+ public void info(Throwable t) {
+ _log.log(Level.INFO, t.getMessage(), t);
+ }
+
+ public void info(Object msg, Throwable t) {
+ _log.log(Level.INFO, msg.toString(), t);
+ }
+
+ public boolean isDebugEnabled() {
+ return _log.isLoggable(Level.FINE);
+ }
+
+ public boolean isErrorEnabled() {
+ return _log.isLoggable(Level.SEVERE);
+ }
+
+ public boolean isFatalEnabled() {
+ return _log.isLoggable(Level.SEVERE);
+ }
+
+ public boolean isInfoEnabled() {
+ return _log.isLoggable(Level.INFO);
+ }
+
+ public boolean isTraceEnabled() {
+ return _log.isLoggable(Level.FINEST);
+ }
+
+ public boolean isWarnEnabled() {
+ return _log.isLoggable(Level.WARNING);
+ }
+
+ public void trace(Object msg) {
+ _log.log(Level.FINEST, msg.toString());
+ }
+
+ public void trace(Throwable t) {
+ _log.log(Level.FINEST, t.getMessage(), t);
+ }
+
+ public void trace(Object msg, Throwable t) {
+ _log.log(Level.FINEST, msg.toString(), t);
+ }
+
+ public void warn(Object msg) {
+ _log.log(Level.WARNING, msg.toString());
+ }
+
+ public void warn(Throwable t) {
+ _log.log(Level.WARNING, t.getMessage(), t);
+ }
+
+ public void warn(Object msg, Throwable t) {
+ _log.log(Level.WARNING, msg.toString(), t);
+ }
+
+ private Logger _log;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Log.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Log.java
new file mode 100644
index 000000000..8723719c5
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/Log.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.log;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public interface Log {
+
+ public void debug(Object msg);
+
+ public void debug(Throwable t);
+
+ public void debug(Object msg, Throwable t);
+
+ public void error(Object msg);
+
+ public void error(Throwable t);
+
+ public void error(Object msg, Throwable t);
+
+ public void fatal(Object msg);
+
+ public void fatal(Throwable t);
+
+ public void fatal(Object msg, Throwable t);
+
+ public void info(Object msg);
+
+ public void info(Throwable t);
+
+ public void info(Object msg, Throwable t);
+
+ public boolean isDebugEnabled();
+
+ public boolean isErrorEnabled();
+
+ public boolean isFatalEnabled();
+
+ public boolean isInfoEnabled();
+
+ public boolean isTraceEnabled();
+
+ public boolean isWarnEnabled();
+
+ public void trace(Object msg);
+
+ public void trace(Throwable t);
+
+ public void trace(Object msg, Throwable t);
+
+ public void warn(Object msg);
+
+ public void warn(Throwable t);
+
+ public void warn(Object msg, Throwable t);
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogFactory.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogFactory.java
new file mode 100644
index 000000000..ecb76ab95
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogFactory.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.log;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public interface LogFactory {
+
+ public Log getLog(Class> c);
+
+ public Log getLog(String name);
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogFactoryUtil.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogFactoryUtil.java
new file mode 100644
index 000000000..5d34326dd
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogFactoryUtil.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.log;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @author Brian Wing Shun Chan
+ * @author Shuyang Zhou
+ */
+public class LogFactoryUtil {
+
+ public static Log getLog(Class> c) {
+ return getLog(c.getName());
+ }
+
+ public static Log getLog(String name) {
+
+ // The following concurrent collection retrieve has the side effect of a
+ // memory fence read. This will invalidate all dirty cache data if there
+ // are any. If the LogWrapper swap happens before this, the new Log will
+ // be visible to the current Thread.
+
+ LogWrapper logWrapper = _logWrappers.get(name);
+
+ if (logWrapper == null) {
+ logWrapper = new LogWrapper(_logFactory.getLog(name));
+
+ LogWrapper previousLogWrapper = _logWrappers.putIfAbsent(
+ name, logWrapper);
+
+ if (previousLogWrapper != null) {
+ logWrapper = previousLogWrapper;
+ }
+ }
+
+ return logWrapper;
+ }
+
+ public static void setLogFactory(LogFactory logFactory) {
+ for (Map.Entry entry : _logWrappers.entrySet()) {
+ String name = entry.getKey();
+
+ LogWrapper logWrapper = entry.getValue();
+
+ logWrapper.setLog(logFactory.getLog(name));
+ }
+
+ // The following volatile write will flush out all cache data. All
+ // previously swapped LogWrappers will be visible for any reads after a
+ // memory fence read according to the happens-before rules.
+
+ _logFactory = logFactory;
+ }
+
+ private static volatile LogFactory _logFactory = new Jdk14LogFactoryImpl();
+ private static final ConcurrentMap _logWrappers =
+ new ConcurrentHashMap();
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogWrapper.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogWrapper.java
new file mode 100644
index 000000000..e0fb6ae32
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/log/LogWrapper.java
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.log;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class LogWrapper implements Log {
+
+ public LogWrapper(Log log) {
+ _log = log;
+ }
+
+ public void setLog(Log log) {
+ _log = log;
+ }
+
+ public void debug(Object msg) {
+ try {
+ _log.debug(msg);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void debug(Throwable t) {
+ try {
+ _log.debug(t);
+ }
+ catch (Exception e) {
+ printMsg(t.getMessage());
+ }
+ }
+
+ public void debug(Object msg, Throwable t) {
+ try {
+ _log.debug(msg, t);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void error(Object msg) {
+ try {
+ _log.error(msg);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void error(Throwable t) {
+ try {
+ _log.error(t);
+ }
+ catch (Exception e) {
+ printMsg(t.getMessage());
+ }
+ }
+
+ public void error(Object msg, Throwable t) {
+ try {
+ _log.error(msg, t);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void fatal(Object msg) {
+ try {
+ _log.fatal(msg);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void fatal(Throwable t) {
+ try {
+ _log.fatal(t);
+ }
+ catch (Exception e) {
+ printMsg(t.getMessage());
+ }
+ }
+
+ public void fatal(Object msg, Throwable t) {
+ try {
+ _log.fatal(msg, t);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void info(Object msg) {
+ try {
+ _log.info(msg);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void info(Throwable t) {
+ try {
+ _log.info(t);
+ }
+ catch (Exception e) {
+ printMsg(t.getMessage());
+ }
+ }
+
+ public void info(Object msg, Throwable t) {
+ try {
+ _log.info(msg, t);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public boolean isDebugEnabled() {
+ return _log.isDebugEnabled();
+ }
+
+ public boolean isErrorEnabled() {
+ return _log.isErrorEnabled();
+ }
+
+ public boolean isFatalEnabled() {
+ return _log.isFatalEnabled();
+ }
+
+ public boolean isInfoEnabled() {
+ return _log.isInfoEnabled();
+ }
+
+ public boolean isTraceEnabled() {
+ return _log.isTraceEnabled();
+ }
+
+ public boolean isWarnEnabled() {
+ return _log.isWarnEnabled();
+ }
+
+ public void trace(Object msg) {
+ try {
+ _log.trace(msg);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void trace(Throwable t) {
+ try {
+ _log.trace(t);
+ }
+ catch (Exception e) {
+ printMsg(t.getMessage());
+ }
+ }
+
+ public void trace(Object msg, Throwable t) {
+ try {
+ _log.trace(msg, t);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void warn(Object msg) {
+ try {
+ _log.warn(msg);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ public void warn(Throwable t) {
+ try {
+ _log.warn(t);
+ }
+ catch (Exception e) {
+ printMsg(t.getMessage());
+ }
+ }
+
+ public void warn(Object msg, Throwable t) {
+ try {
+ _log.warn(msg, t);
+ }
+ catch (Exception e) {
+ printMsg(msg);
+ }
+ }
+
+ protected void printMsg(Object msg) {
+ System.err.println(msg);
+ }
+
+ private Log _log;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/CharPool.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/CharPool.java
new file mode 100644
index 000000000..f85518f6c
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/CharPool.java
@@ -0,0 +1,216 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class CharPool {
+
+ public static final char AMPERSAND = '&';
+
+ public static final char APOSTROPHE = '\'';
+
+ public static final char AT = '@';
+
+ public static final char BACK_SLASH = '\\';
+
+ public static final char CLOSE_BRACKET = ']';
+
+ public static final char CLOSE_CURLY_BRACE = '}';
+
+ public static final char CLOSE_PARENTHESIS = ')';
+
+ public static final char COLON = ':';
+
+ public static final char COMMA = ',';
+
+ public static final char DASH = '-';
+
+ public static final char EQUAL = '=';
+
+ public static final char GREATER_THAN = '>';
+
+ public static final char FORWARD_SLASH = '/';
+
+ public static final char LESS_THAN = '<';
+
+ public static final char LOWER_CASE_A = 'a';
+
+ public static final char LOWER_CASE_B = 'b';
+
+ public static final char LOWER_CASE_C = 'c';
+
+ public static final char LOWER_CASE_D = 'd';
+
+ public static final char LOWER_CASE_E = 'e';
+
+ public static final char LOWER_CASE_F = 'f';
+
+ public static final char LOWER_CASE_G = 'g';
+
+ public static final char LOWER_CASE_H = 'h';
+
+ public static final char LOWER_CASE_I = 'i';
+
+ public static final char LOWER_CASE_J = 'j';
+
+ public static final char LOWER_CASE_K = 'k';
+
+ public static final char LOWER_CASE_L = 'l';
+
+ public static final char LOWER_CASE_M = 'm';
+
+ public static final char LOWER_CASE_N = 'n';
+
+ public static final char LOWER_CASE_O = 'o';
+
+ public static final char LOWER_CASE_P = 'p';
+
+ public static final char LOWER_CASE_Q = 'q';
+
+ public static final char LOWER_CASE_R = 'r';
+
+ public static final char LOWER_CASE_S = 's';
+
+ public static final char LOWER_CASE_T = 't';
+
+ public static final char LOWER_CASE_U = 'u';
+
+ public static final char LOWER_CASE_V = 'v';
+
+ public static final char LOWER_CASE_W = 'w';
+
+ public static final char LOWER_CASE_X = 'x';
+
+ public static final char LOWER_CASE_Y = 'y';
+
+ public static final char LOWER_CASE_Z = 'z';
+
+ public static final char MINUS = '-';
+
+ public static final char NEW_LINE = '\n';
+
+ public static final char NUMBER_0 = '0';
+
+ public static final char NUMBER_1 = '1';
+
+ public static final char NUMBER_2 = '2';
+
+ public static final char NUMBER_3 = '3';
+
+ public static final char NUMBER_4 = '4';
+
+ public static final char NUMBER_5 = '5';
+
+ public static final char NUMBER_6 = '6';
+
+ public static final char NUMBER_7 = '7';
+
+ public static final char NUMBER_8 = '8';
+
+ public static final char NUMBER_9 = '9';
+
+ public static final char OPEN_BRACKET = '[';
+
+ public static final char OPEN_CURLY_BRACE = '{';
+
+ public static final char OPEN_PARENTHESIS = '(';
+
+ public static final char PERCENT = '%';
+
+ public static final char PERIOD = '.';
+
+ public static final char PIPE = '|';
+
+ public static final char PLUS = '+';
+
+ public static final char POUND = '#';
+
+ public static final char QUESTION = '?';
+
+ public static final char QUOTE = '\"';
+
+ public static final char RAQUO = '\u00bb'; // '�'
+
+ public static final char RETURN = '\r';
+
+ public static final char SEMICOLON = ';';
+
+ public static final char SLASH = FORWARD_SLASH;
+
+ public static final char SPACE = ' ';
+
+ public static final char STAR = '*';
+
+ public static final char TAB = '\t';
+
+ public static final char TILDE = '~';
+
+ public static final char UNDERLINE = '_';
+
+ public static final char UPPER_CASE_A = 'A';
+
+ public static final char UPPER_CASE_B = 'B';
+
+ public static final char UPPER_CASE_C = 'C';
+
+ public static final char UPPER_CASE_D = 'D';
+
+ public static final char UPPER_CASE_E = 'E';
+
+ public static final char UPPER_CASE_F = 'F';
+
+ public static final char UPPER_CASE_G = 'G';
+
+ public static final char UPPER_CASE_H = 'H';
+
+ public static final char UPPER_CASE_I = 'I';
+
+ public static final char UPPER_CASE_J = 'J';
+
+ public static final char UPPER_CASE_K = 'K';
+
+ public static final char UPPER_CASE_L = 'L';
+
+ public static final char UPPER_CASE_M = 'M';
+
+ public static final char UPPER_CASE_N = 'N';
+
+ public static final char UPPER_CASE_O = 'O';
+
+ public static final char UPPER_CASE_P = 'P';
+
+ public static final char UPPER_CASE_Q = 'Q';
+
+ public static final char UPPER_CASE_R = 'R';
+
+ public static final char UPPER_CASE_S = 'S';
+
+ public static final char UPPER_CASE_T = 'T';
+
+ public static final char UPPER_CASE_U = 'U';
+
+ public static final char UPPER_CASE_V = 'V';
+
+ public static final char UPPER_CASE_W = 'W';
+
+ public static final char UPPER_CASE_X = 'X';
+
+ public static final char UPPER_CASE_Y = 'Y';
+
+ public static final char UPPER_CASE_Z = 'Z';
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/ClassUtil.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/ClassUtil.java
new file mode 100644
index 000000000..059057e4b
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/ClassUtil.java
@@ -0,0 +1,332 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
+import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StreamTokenizer;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Brian Wing Shun Chan
+ * @author Sandeep Soni
+ */
+public class ClassUtil {
+
+ public static Set getClasses(File file) throws IOException {
+ String fileName = file.getName();
+
+ if (fileName.endsWith(".java")) {
+ fileName = fileName.substring(0, fileName.length() - 5);
+ }
+
+ return getClasses(new FileReader(file), fileName);
+ }
+
+ public static Set getClasses(Reader reader, String className)
+ throws IOException {
+
+ Set classes = new HashSet();
+
+ StreamTokenizer st = new StreamTokenizer(
+ new UnsyncBufferedReader(reader));
+
+ _setupParseTableForAnnotationProcessing(st);
+
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ if (st.sval.equals("class") || st.sval.equals("enum") ||
+ st.sval.equals("interface") ||
+ st.sval.equals("@interface")) {
+
+ break;
+ }
+ else if (st.sval.startsWith("@")) {
+ st.ordinaryChar(' ');
+ st.wordChars('=', '=');
+
+ String[] las = _processAnnotation(st.sval, st);
+
+ for (int i = 0; i < las.length; i++) {
+ classes.add(las[i]);
+ }
+
+ _setupParseTableForAnnotationProcessing(st);
+ }
+ }
+ }
+
+ _setupParseTable(st);
+
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ if (st.sval.indexOf('.') >= 0) {
+ classes.add(st.sval.substring(0, st.sval.indexOf('.')));
+ }
+ else {
+ classes.add(st.sval);
+ }
+ }
+ else if (st.ttype != StreamTokenizer.TT_NUMBER &&
+ st.ttype != StreamTokenizer.TT_EOL) {
+
+ if (Character.isUpperCase((char)st.ttype)) {
+ classes.add(String.valueOf((char)st.ttype));
+ }
+ }
+ }
+
+ classes.remove(className);
+
+ return classes;
+ }
+
+ public static String getParentPath(
+ ClassLoader classLoader, String className) {
+
+ if (_log.isDebugEnabled()) {
+ _log.debug("Class name " + className);
+ }
+
+ if (!className.endsWith(_CLASS_EXTENSION)) {
+ className += _CLASS_EXTENSION;
+ }
+
+ className = StringUtil.replace(
+ className, StringPool.PERIOD, StringPool.SLASH);
+
+ className = StringUtil.replace(className, "/class", _CLASS_EXTENSION);
+
+ URL url = classLoader.getResource(className);
+
+ String path = null;
+
+ try {
+ path = new URI(url.getPath()).getPath();
+ }
+ catch (URISyntaxException urise) {
+ path = url.getFile();
+ }
+
+ if (_log.isDebugEnabled()) {
+ _log.debug("Path " + path);
+ }
+
+ int pos = path.indexOf(className);
+
+ String parentPath = path.substring(0, pos);
+
+ if (parentPath.startsWith("jar:")) {
+ parentPath = parentPath.substring(4, parentPath.length());
+ }
+
+ if (parentPath.startsWith("file:/")) {
+ parentPath = parentPath.substring(6, parentPath.length());
+ }
+
+ if (_log.isDebugEnabled()) {
+ _log.debug("Parent path " + parentPath);
+ }
+
+ return parentPath;
+ }
+
+ public static boolean isSubclass(Class> a, Class> b) {
+ if (a == b) {
+ return true;
+ }
+
+ if (a == null || b == null) {
+ return false;
+ }
+
+ for (Class> x = a; x != null; x = x.getSuperclass()) {
+ if (x == b) {
+ return true;
+ }
+
+ if (b.isInterface()) {
+ Class>[] interfaces = x.getInterfaces();
+
+ for (int i = 0; i < interfaces.length; i++) {
+ if (isSubclass(interfaces[i], b)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static boolean isSubclass(Class> a, String s) {
+ if (a == null || s == null) {
+ return false;
+ }
+
+ if (a.getName().equals(s)) {
+ return true;
+ }
+
+ for (Class> x = a; x != null; x = x.getSuperclass()) {
+ if (x.getName().equals(s)) {
+ return true;
+ }
+
+ Class>[] interfaces = x.getInterfaces();
+
+ for (int i = 0; i < interfaces.length; i++) {
+ if (isSubclass(interfaces[i], s)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static String[] _processAnnotation(String s, StreamTokenizer st)
+ throws IOException {
+
+ s = s.trim();
+
+ List tokens = new ArrayList();
+
+ Matcher annotationNameMatcher = _ANNOTATION_NAME_REGEXP.matcher(s);
+ Matcher annotationParametersMatcher =
+ _ANNOTATION_PARAMETERS_REGEXP.matcher(s);
+
+ if (annotationNameMatcher.matches()) {
+ String annotationName = annotationNameMatcher.group();
+
+ tokens.add(annotationName.replace("@", ""));
+ }
+ else if (annotationParametersMatcher.matches()) {
+ if (!s.trim().endsWith(")")) {
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ s += st.sval;
+ if (s.trim().endsWith(")")) {
+ break;
+ }
+ }
+ }
+ }
+
+ annotationParametersMatcher =
+ _ANNOTATION_PARAMETERS_REGEXP.matcher(s);
+
+ if (annotationParametersMatcher.matches()) {
+ String annotationName =
+ annotationParametersMatcher.group(1);
+ String annotationParameters =
+ annotationParametersMatcher.group(2);
+
+ tokens.add(annotationName.replace("@", ""));
+
+ tokens = _processAnnotationParameters(
+ annotationParameters,tokens);
+ }
+ }
+
+ return tokens.toArray(new String[tokens.size()]);
+ }
+
+ private static List _processAnnotationParameters(
+ String s, List tokens)
+ throws IOException {
+
+ StreamTokenizer st = new StreamTokenizer(new UnsyncStringReader(s));
+
+ _setupParseTable(st);
+
+ while (st.nextToken() != StreamTokenizer.TT_EOF) {
+ if (st.ttype == StreamTokenizer.TT_WORD) {
+ if (st.sval.indexOf('.') >= 0) {
+ tokens.add(st.sval.substring(0, st.sval.indexOf('.')));
+ }
+ else {
+ tokens.add(st.sval);
+ }
+ }
+ else if ((st.ttype != StreamTokenizer.TT_NUMBER) &&
+ (st.ttype != StreamTokenizer.TT_EOL)) {
+
+ if (Character.isUpperCase((char)st.ttype)) {
+ tokens.add(String.valueOf((char)st.ttype));
+ }
+ }
+ }
+
+ return tokens;
+ }
+
+ private static void _setupParseTable(StreamTokenizer st) {
+ st.resetSyntax();
+ st.slashSlashComments(true);
+ st.slashStarComments(true);
+ st.wordChars('a', 'z');
+ st.wordChars('A', 'Z');
+ st.wordChars('.', '.');
+ st.wordChars('0', '9');
+ st.wordChars('_', '_');
+ st.lowerCaseMode(false);
+ st.eolIsSignificant(false);
+ st.quoteChar('"');
+ st.quoteChar('\'');
+ st.parseNumbers();
+ }
+
+ private static void _setupParseTableForAnnotationProcessing(
+ StreamTokenizer st) {
+
+ _setupParseTable(st);
+
+ st.wordChars('@', '@');
+ st.wordChars('(', '(');
+ st.wordChars(')', ')');
+ st.wordChars('{', '{');
+ st.wordChars('}', '}');
+ st.wordChars(',',',');
+ }
+
+ private static final Pattern _ANNOTATION_NAME_REGEXP =
+ Pattern.compile("@(\\w+)$");
+
+ private static final Pattern _ANNOTATION_PARAMETERS_REGEXP =
+ Pattern.compile("@(\\w+)\\({0,1}\\{{0,1}([^)}]+)\\}{0,1}\\){0,1}");
+
+ private static final String _CLASS_EXTENSION = ".class";
+
+ private static Log _log = LogFactoryUtil.getLog(ClassUtil.class);
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/File.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/File.java
new file mode 100644
index 000000000..93323561e
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/File.java
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * @author Brian Wing Shun Chan
+ * @author Alexander Chow
+ */
+public interface File {
+
+ public void copyDirectory(String sourceDirName, String destinationDirName);
+
+ public void copyDirectory(java.io.File source, java.io.File destination);
+
+ public void copyFile(String source, String destination);
+
+ public void copyFile(String source, String destination, boolean lazy);
+
+ public void copyFile(java.io.File source, java.io.File destination);
+
+ public void copyFile(
+ java.io.File source, java.io.File destination, boolean lazy);
+
+ public java.io.File createTempFile();
+
+ public java.io.File createTempFile(String extension);
+
+ public String createTempFileName();
+
+ public String createTempFileName(String extension);
+
+ public String decodeSafeFileName(String fileName);
+
+ public boolean delete(String file);
+
+ public boolean delete(java.io.File file);
+
+ public void deltree(String directory);
+
+ public void deltree(java.io.File directory);
+
+ public String encodeSafeFileName(String fileName);
+
+ public boolean exists(String fileName);
+
+ public boolean exists(java.io.File file);
+
+ public String extractText(InputStream is, String fileName);
+
+ public String getAbsolutePath(java.io.File file);
+
+ public byte[] getBytes(java.io.File file) throws IOException;
+
+ public byte[] getBytes(InputStream is) throws IOException;
+
+ public byte[] getBytes(InputStream is, int bufferSize) throws IOException;
+
+ public String getExtension(String fileName);
+
+ public String getPath(String fullFileName);
+
+ public String getShortFileName(String fullFileName);
+
+ public boolean isAscii(java.io.File file) throws IOException;
+
+ public String[] listDirs(String fileName);
+
+ public String[] listDirs(java.io.File file);
+
+ public String[] listFiles(String fileName);
+
+ public String[] listFiles(java.io.File file);
+
+ public void mkdirs(String pathName);
+
+ public boolean move(String sourceFileName, String destinationFileName);
+
+ public boolean move(java.io.File source, java.io.File destination);
+
+ public String read(String fileName) throws IOException;
+
+ public String read(java.io.File file) throws IOException;
+
+ public String read(java.io.File file, boolean raw) throws IOException;
+
+ public String replaceSeparator(String fileName);
+
+ public java.io.File[] sortFiles(java.io.File[] files);
+
+ public String stripExtension(String fileName);
+
+ public List toList(Reader reader);
+
+ public List toList(String fileName);
+
+ public Properties toProperties(java.io.FileInputStream fis);
+
+ public Properties toProperties(String fileName);
+
+ public void write(String fileName, String s) throws IOException;
+
+ public void write(String fileName, String s, boolean lazy)
+ throws IOException;
+
+ public void write(String fileName, String s, boolean lazy, boolean append)
+ throws IOException;
+
+ public void write(String pathName, String fileName, String s)
+ throws IOException;
+
+ public void write(String pathName, String fileName, String s, boolean lazy)
+ throws IOException;
+
+ public void write(
+ String pathName, String fileName, String s, boolean lazy,
+ boolean append)
+ throws IOException;
+
+ public void write(java.io.File file, String s) throws IOException;
+
+ public void write(java.io.File file, String s, boolean lazy)
+ throws IOException;
+
+ public void write(java.io.File file, String s, boolean lazy, boolean append)
+ throws IOException;
+
+ public void write(String fileName, byte[] bytes) throws IOException;
+
+ public void write(java.io.File file, byte[] bytes) throws IOException;
+
+ public void write(java.io.File file, byte[] bytes, int offset, int length)
+ throws IOException;
+
+ public void write(String fileName, InputStream is) throws IOException;
+
+ public void write(java.io.File file, InputStream is) throws IOException;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/FileUtil.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/FileUtil.java
new file mode 100644
index 000000000..6d7105795
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/FileUtil.java
@@ -0,0 +1,313 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * @author Brian Wing Shun Chan
+ * @author Alexander Chow
+ */
+public class FileUtil {
+
+ public static void copyDirectory(
+ String sourceDirName, String destinationDirName) {
+
+ getFile().copyDirectory(sourceDirName, destinationDirName);
+ }
+
+ public static void copyDirectory(File source, File destination) {
+ getFile().copyDirectory(source, destination);
+ }
+
+ public static void copyFile(String source, String destination) {
+ getFile().copyFile(source, destination);
+ }
+
+ public static void copyFile(
+ String source, String destination, boolean lazy) {
+
+ getFile().copyFile(source, destination, lazy);
+ }
+
+ public static void copyFile(File source, File destination) {
+ getFile().copyFile(source, destination);
+ }
+
+ public static void copyFile(File source, File destination, boolean lazy) {
+ getFile().copyFile(source, destination, lazy);
+ }
+
+ public static File createTempFile() {
+ return getFile().createTempFile();
+ }
+
+ public static File createTempFile(String extension) {
+ return getFile().createTempFile(extension);
+ }
+
+ public static String createTempFileName() {
+ return getFile().createTempFileName();
+ }
+
+ public static String createTempFileName(String extension) {
+ return getFile().createTempFileName(extension);
+ }
+
+ public static String decodeSafeFileName(String fileName) {
+ return getFile().decodeSafeFileName(fileName);
+ }
+
+ public static boolean delete(String file) {
+ return getFile().delete(file);
+ }
+
+ public static boolean delete(File file) {
+ return getFile().delete(file);
+ }
+
+ public static void deltree(String directory) {
+ getFile().deltree(directory);
+ }
+
+ public static void deltree(File directory) {
+ getFile().deltree(directory);
+ }
+
+ public static String encodeSafeFileName(String fileName) {
+ return getFile().encodeSafeFileName(fileName);
+ }
+
+ public static boolean exists(String fileName) {
+ return getFile().exists(fileName);
+ }
+
+ public static boolean exists(File file) {
+ return getFile().exists(file);
+ }
+
+ /**
+ * Extract text from an input stream and file name.
+ *
+ * @param is input stream of file
+ * @param fileName full name or extension of file (e.g., "Test.doc",
+ * ".doc")
+ * @return Extracted text if it is a supported format or an empty string if
+ * it is an unsupported format
+ */
+ public static String extractText(InputStream is, String fileName) {
+ return getFile().extractText(is, fileName);
+ }
+
+ public static String getAbsolutePath(File file) {
+ return getFile().getAbsolutePath(file);
+ }
+
+ public static byte[] getBytes(File file) throws IOException {
+ return getFile().getBytes(file);
+ }
+
+ public static byte[] getBytes(InputStream is) throws IOException {
+ return getFile().getBytes(is);
+ }
+
+ public static byte[] getBytes(InputStream is, int bufferSize)
+ throws IOException {
+
+ return getFile().getBytes(is);
+ }
+
+ public static String getExtension(String fileName) {
+ return getFile().getExtension(fileName);
+ }
+
+ public static com.liferay.portal.kernel.util.File getFile() {
+ return _file;
+ }
+
+ public static String getPath(String fullFileName) {
+ return getFile().getPath(fullFileName);
+ }
+
+ public static String getShortFileName(String fullFileName) {
+ return getFile().getShortFileName(fullFileName);
+ }
+
+ public static boolean isAscii(File file) throws IOException {
+ return getFile().isAscii(file);
+ }
+
+ public static String[] listDirs(String fileName) {
+ return getFile().listDirs(fileName);
+ }
+
+ public static String[] listDirs(File file) {
+ return getFile().listDirs(file);
+ }
+
+ public static String[] listFiles(String fileName) {
+ return getFile().listFiles(fileName);
+ }
+
+ public static String[] listFiles(File file) {
+ return getFile().listFiles(file);
+ }
+
+ public static void mkdirs(String pathName) {
+ getFile().mkdirs(pathName);
+ }
+
+ public static boolean move(
+ String sourceFileName, String destinationFileName) {
+
+ return getFile().move(sourceFileName, destinationFileName);
+ }
+
+ public static boolean move(File source, File destination) {
+ return getFile().move(source, destination);
+ }
+
+ public static String read(String fileName) throws IOException {
+ return getFile().read(fileName);
+ }
+
+ public static String read(File file) throws IOException {
+ return getFile().read(file);
+ }
+
+ public static String read(File file, boolean raw) throws IOException {
+ return getFile().read(file, raw);
+ }
+
+ public static String replaceSeparator(String fileName) {
+ return getFile().replaceSeparator(fileName);
+ }
+
+ public static File[] sortFiles(File[] files) {
+ return getFile().sortFiles(files);
+ }
+
+ public static String stripExtension(String fileName) {
+ return getFile().stripExtension(fileName);
+ }
+
+ public static List toList(Reader reader) {
+ return getFile().toList(reader);
+ }
+
+ public static List toList(String fileName) {
+ return getFile().toList(fileName);
+ }
+
+ public static Properties toProperties(FileInputStream fis) {
+ return getFile().toProperties(fis);
+ }
+
+ public static Properties toProperties(String fileName) {
+ return getFile().toProperties(fileName);
+ }
+
+ public static void write(String fileName, String s) throws IOException {
+ getFile().write(fileName, s);
+ }
+
+ public static void write(String fileName, String s, boolean lazy)
+ throws IOException {
+
+ getFile().write(fileName, s, lazy);
+ }
+
+ public static void write(
+ String fileName, String s, boolean lazy, boolean append)
+ throws IOException {
+
+ getFile().write(fileName, s, lazy, append);
+ }
+
+ public static void write(String pathName, String fileName, String s)
+ throws IOException {
+
+ getFile().write(pathName, fileName, s);
+ }
+
+ public static void write(
+ String pathName, String fileName, String s, boolean lazy)
+ throws IOException {
+
+ getFile().write(pathName, fileName, s, lazy);
+ }
+
+ public static void write(
+ String pathName, String fileName, String s, boolean lazy,
+ boolean append)
+ throws IOException {
+
+ getFile().write(pathName, fileName, s, lazy, append);
+ }
+
+ public static void write(File file, String s) throws IOException {
+ getFile().write(file, s);
+ }
+
+ public static void write(File file, String s, boolean lazy)
+ throws IOException {
+
+ getFile().write(file, s, lazy);
+ }
+
+ public static void write(File file, String s, boolean lazy, boolean append)
+ throws IOException {
+
+ getFile().write(file, s, lazy, append);
+ }
+
+ public static void write(String fileName, byte[] bytes) throws IOException {
+ getFile().write(fileName, bytes);
+ }
+
+ public static void write(File file, byte[] bytes) throws IOException {
+ getFile().write(file, bytes);
+ }
+
+ public static void write(File file, byte[] bytes, int offset, int length)
+ throws IOException {
+
+ getFile().write(file, bytes, offset, length);
+ }
+
+ public static void write(String fileName, InputStream is)
+ throws IOException {
+
+ getFile().write(fileName, is);
+ }
+
+ public static void write(File file, InputStream is) throws IOException {
+ getFile().write(file, is);
+ }
+
+ public void setFile(com.liferay.portal.kernel.util.File file) {
+ _file = file;
+ }
+
+ private static com.liferay.portal.kernel.util.File _file;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/GetterUtil.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/GetterUtil.java
new file mode 100644
index 000000000..4ec404632
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/GetterUtil.java
@@ -0,0 +1,875 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.Serializable;
+
+import java.text.DateFormat;
+
+import java.util.Date;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class GetterUtil {
+
+ public static String[] BOOLEANS = {"true", "t", "y", "on", "1"};
+
+ public static final boolean DEFAULT_BOOLEAN = false;
+
+ public static final boolean[] DEFAULT_BOOLEAN_VALUES = new boolean[0];
+
+ public static final byte DEFAULT_BYTE = 0;
+
+ public static final byte[] DEFAULT_BYTE_VALUES = new byte[0];
+
+ public static final Date[] DEFAULT_DATE_VALUES = new Date[0];
+
+ public static final double DEFAULT_DOUBLE = 0.0;
+
+ public static final double[] DEFAULT_DOUBLE_VALUES = new double[0];
+
+ public static final float DEFAULT_FLOAT = 0;
+
+ public static final float[] DEFAULT_FLOAT_VALUES = new float[0];
+
+ public static final int DEFAULT_INTEGER = 0;
+
+ public static final int[] DEFAULT_INTEGER_VALUES = new int[0];
+
+ public static final long DEFAULT_LONG = 0;
+
+ public static final long[] DEFAULT_LONG_VALUES = new long[0];
+
+ public static final short DEFAULT_SHORT = 0;
+
+ public static final short[] DEFAULT_SHORT_VALUES = new short[0];
+
+ public static final String DEFAULT_STRING = StringPool.BLANK;
+
+ public static boolean get(Serializable value, boolean defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ if (value instanceof String) {
+ return get((String)value, defaultValue);
+ }
+ else if (value.getClass().isAssignableFrom(Boolean.class)) {
+ return (Boolean)value;
+ }
+
+ return defaultValue;
+ }
+
+ public static Date get(
+ Serializable value, DateFormat dateFormat, Date defaultValue) {
+
+ if (value == null) {
+ return defaultValue;
+ }
+
+ if (value instanceof String) {
+ return get((String)value, dateFormat, defaultValue);
+ }
+ else if (value.getClass().isAssignableFrom(Date.class)) {
+ return (Date)value;
+ }
+
+ return defaultValue;
+ }
+
+ public static double get(Serializable value, double defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ if (value instanceof String) {
+ return get((String)value, defaultValue);
+ }
+ else if (value.getClass().isAssignableFrom(Double.class)) {
+ return (Double)value;
+ }
+
+ return defaultValue;
+ }
+
+ public static float get(Serializable value, float defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ if (value instanceof String) {
+ return get((String)value, defaultValue);
+ }
+ else if (value.getClass().isAssignableFrom(Float.class)) {
+ return (Float)value;
+ }
+
+ return defaultValue;
+ }
+
+ public static int get(Serializable value, int defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ if (value instanceof String) {
+ return get((String)value, defaultValue);
+ }
+ else if (value.getClass().isAssignableFrom(Integer.class)) {
+ return (Integer)value;
+ }
+
+ return defaultValue;
+ }
+
+ public static long get(Serializable value, long defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ if (value instanceof String) {
+ return get((String)value, defaultValue);
+ }
+ else if (value.getClass().isAssignableFrom(Long.class)) {
+ return (Long)value;
+ }
+
+ return defaultValue;
+ }
+
+ public static short get(Serializable value, short defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ if (value instanceof String) {
+ return get((String)value, defaultValue);
+ }
+ else if (value.getClass().isAssignableFrom(Short.class)) {
+ return (Short)value;
+ }
+
+ return defaultValue;
+ }
+
+ public static String get(Serializable value, String defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ if (value instanceof String) {
+ return get((String)value, defaultValue);
+ }
+
+ return defaultValue;
+ }
+
+ public static boolean get(String value, boolean defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ try {
+ value = value.trim();
+
+ if (value.equalsIgnoreCase(BOOLEANS[0]) ||
+ value.equalsIgnoreCase(BOOLEANS[1]) ||
+ value.equalsIgnoreCase(BOOLEANS[2]) ||
+ value.equalsIgnoreCase(BOOLEANS[3]) ||
+ value.equalsIgnoreCase(BOOLEANS[4])) {
+
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ catch (Exception e) {
+ }
+
+ return defaultValue;
+ }
+
+ public static Date get(
+ String value, DateFormat dateFormat, Date defaultValue) {
+
+ if (value == null) {
+ return defaultValue;
+ }
+
+ try {
+ Date date = dateFormat.parse(value.trim());
+
+ if (date != null) {
+ return date;
+ }
+ }
+ catch (Exception e) {
+ }
+
+ return defaultValue;
+ }
+
+ public static double get(String value, double defaultValue) {
+ if (value != null) {
+ try {
+ return Double.parseDouble(_trim(value));
+ }
+ catch (Exception e) {
+ }
+ }
+
+ return defaultValue;
+ }
+
+ public static float get(String value, float defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ try {
+ return Float.parseFloat(_trim(value));
+ }
+ catch (Exception e) {
+ }
+
+ return defaultValue;
+ }
+
+ public static int get(String value, int defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ return _parseInt(_trim(value), defaultValue);
+ }
+
+ public static long get(String value, long defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ return _parseLong(_trim(value), defaultValue);
+ }
+
+ public static short get(String value, short defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ return _parseShort(_trim(value), defaultValue);
+ }
+
+ public static String get(String value, String defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ }
+
+ return StringUtil.replace(
+ value.trim(), StringPool.RETURN_NEW_LINE, StringPool.NEW_LINE);
+ }
+
+ public static boolean getBoolean(Serializable value) {
+ return getBoolean(value, DEFAULT_BOOLEAN);
+ }
+
+ public static boolean getBoolean(Serializable value, boolean defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static boolean getBoolean(String value) {
+ return getBoolean(value, DEFAULT_BOOLEAN);
+ }
+
+ public static boolean getBoolean(String value, boolean defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static boolean[] getBooleanValues(Serializable value) {
+ return getBooleanValues(value, DEFAULT_BOOLEAN_VALUES);
+ }
+
+ public static boolean[] getBooleanValues(
+ Serializable value, boolean[] defaultValue) {
+
+ Class> classObject = value.getClass();
+
+ if (classObject.isArray()) {
+ Class> componentType = classObject.getComponentType();
+
+ if (componentType.isAssignableFrom(String.class)) {
+ return getBooleanValues((String[])value, defaultValue);
+ }
+ else if (componentType.isAssignableFrom(Boolean.class)) {
+ return (boolean[])value;
+ }
+ }
+
+ return defaultValue;
+ }
+
+ public static boolean[] getBooleanValues(String[] values) {
+ return getBooleanValues(values, DEFAULT_BOOLEAN_VALUES);
+ }
+
+ public static boolean[] getBooleanValues(
+ String[] values, boolean[] defaultValue) {
+
+ if (values == null) {
+ return defaultValue;
+ }
+
+ boolean[] booleanValues = new boolean[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ booleanValues[i] = getBoolean(values[i]);
+ }
+
+ return booleanValues;
+ }
+
+ public static Date getDate(Serializable value, DateFormat dateFormat) {
+ return getDate(value, dateFormat, new Date());
+ }
+
+ public static Date getDate(
+ Serializable value, DateFormat dateFormat, Date defaultValue) {
+
+ return get(value, dateFormat, defaultValue);
+ }
+
+ public static Date getDate(String value, DateFormat dateFormat) {
+ return getDate(value, dateFormat, new Date());
+ }
+
+ public static Date getDate(
+ String value, DateFormat dateFormat, Date defaultValue) {
+
+ return get(value, dateFormat, defaultValue);
+ }
+
+ public static Date[] getDateValues(
+ Serializable value, DateFormat dateFormat) {
+
+ return getDateValues(value, dateFormat, DEFAULT_DATE_VALUES);
+ }
+
+ public static Date[] getDateValues(
+ Serializable value, DateFormat dateFormat, Date[] defaultValue) {
+
+ Class> classObject = value.getClass();
+
+ if (classObject.isArray()) {
+ Class> componentType = classObject.getComponentType();
+
+ if (componentType.isAssignableFrom(String.class)) {
+ return getDateValues((String[])value, dateFormat, defaultValue);
+ }
+ else if (componentType.isAssignableFrom(Date.class)) {
+ return (Date[])value;
+ }
+ }
+
+ return defaultValue;
+ }
+
+ public static Date[] getDateValues(String[] values, DateFormat dateFormat) {
+ return getDateValues(values, dateFormat, DEFAULT_DATE_VALUES);
+ }
+
+ public static Date[] getDateValues(
+ String[] values, DateFormat dateFormat, Date[] defaultValue) {
+
+ if (values == null) {
+ return defaultValue;
+ }
+
+ Date[] dateValues = new Date[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ dateValues[i] = getDate(values[i], dateFormat);
+ }
+
+ return dateValues;
+ }
+
+ public static double getDouble(Serializable value) {
+ return getDouble(value, DEFAULT_DOUBLE);
+ }
+
+ public static double getDouble(Serializable value, double defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static double getDouble(String value) {
+ return getDouble(value, DEFAULT_DOUBLE);
+ }
+
+ public static double getDouble(String value, double defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static double[] getDoubleValues(Serializable value) {
+ return getDoubleValues(value, DEFAULT_DOUBLE_VALUES);
+ }
+
+ public static double[] getDoubleValues(
+ Serializable value, double[] defaultValue) {
+
+ Class> classObject = value.getClass();
+
+ if (classObject.isArray()) {
+ Class> componentType = classObject.getComponentType();
+
+ if (componentType.isAssignableFrom(String.class)) {
+ return getDoubleValues((String[])value, defaultValue);
+ }
+ else if (componentType.isAssignableFrom(Double.class)) {
+ return (double[])value;
+ }
+ }
+
+ return defaultValue;
+ }
+
+ public static double[] getDoubleValues(String[] values) {
+ return getDoubleValues(values, DEFAULT_DOUBLE_VALUES);
+ }
+
+ public static double[] getDoubleValues(
+ String[] values, double[] defaultValue) {
+
+ if (values == null) {
+ return defaultValue;
+ }
+
+ double[] doubleValues = new double[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ doubleValues[i] = getDouble(values[i]);
+ }
+
+ return doubleValues;
+ }
+
+ public static float getFloat(Serializable value) {
+ return getFloat(value, DEFAULT_FLOAT);
+ }
+
+ public static float getFloat(Serializable value, float defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static float getFloat(String value) {
+ return getFloat(value, DEFAULT_FLOAT);
+ }
+
+ public static float getFloat(String value, float defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static float[] getFloatValues(Serializable value) {
+ return getFloatValues(value, DEFAULT_FLOAT_VALUES);
+ }
+
+ public static float[] getFloatValues(
+ Serializable value, float[] defaultValue) {
+
+ Class> classObject = value.getClass();
+
+ if (classObject.isArray()) {
+ Class> componentType = classObject.getComponentType();
+
+ if (componentType.isAssignableFrom(String.class)) {
+ return getFloatValues((String[])value, defaultValue);
+ }
+ else if (componentType.isAssignableFrom(Float.class)) {
+ return (float[])value;
+ }
+ }
+
+ return defaultValue;
+ }
+
+ public static float[] getFloatValues(String[] values) {
+ return getFloatValues(values, DEFAULT_FLOAT_VALUES);
+ }
+
+ public static float[] getFloatValues(
+ String[] values, float[] defaultValue) {
+
+ if (values == null) {
+ return defaultValue;
+ }
+
+ float[] floatValues = new float[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ floatValues[i] = getFloat(values[i]);
+ }
+
+ return floatValues;
+ }
+
+ public static int getInteger(Serializable value) {
+ return getInteger(value, DEFAULT_INTEGER);
+ }
+
+ public static int getInteger(Serializable value, int defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static int getInteger(String value) {
+ return getInteger(value, DEFAULT_INTEGER);
+ }
+
+ public static int getInteger(String value, int defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static int[] getIntegerValues(Serializable value) {
+ return getIntegerValues(value, DEFAULT_INTEGER_VALUES);
+ }
+
+ public static int[] getIntegerValues(
+ Serializable value, int[] defaultValue) {
+
+ Class> classObject = value.getClass();
+
+ if (classObject.isArray()) {
+ Class> componentType = classObject.getComponentType();
+
+ if (componentType.isAssignableFrom(String.class)) {
+ return getIntegerValues((String[])value, defaultValue);
+ }
+ else if (componentType.isAssignableFrom(Integer.class)) {
+ return (int[])value;
+ }
+ }
+
+ return defaultValue;
+ }
+
+ public static int[] getIntegerValues(String[] values) {
+ return getIntegerValues(values, DEFAULT_INTEGER_VALUES);
+ }
+
+ public static int[] getIntegerValues(String[] values, int[] defaultValue) {
+ if (values == null) {
+ return defaultValue;
+ }
+
+ int[] intValues = new int[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ intValues[i] = getInteger(values[i]);
+ }
+
+ return intValues;
+ }
+
+ public static long getLong(Serializable value) {
+ return getLong(value, DEFAULT_LONG);
+ }
+
+ public static long getLong(Serializable value, long defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static long getLong(String value) {
+ return getLong(value, DEFAULT_LONG);
+ }
+
+ public static long getLong(String value, long defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static long[] getLongValues(Serializable value) {
+ return getLongValues(value, DEFAULT_LONG_VALUES);
+ }
+
+ public static long[] getLongValues(
+ Serializable value, long[] defaultValue) {
+
+ Class> classObject = value.getClass();
+
+ if (classObject.isArray()) {
+ Class> componentType = classObject.getComponentType();
+
+ if (componentType.isAssignableFrom(String.class)) {
+ return getLongValues((String[])value, defaultValue);
+ }
+ else if (componentType.isAssignableFrom(Long.class)) {
+ return (long[])value;
+ }
+ }
+
+ return defaultValue;
+ }
+
+ public static long[] getLongValues(String[] values) {
+ return getLongValues(values, DEFAULT_LONG_VALUES);
+ }
+
+ public static long[] getLongValues(String[] values, long[] defaultValue) {
+ if (values == null) {
+ return defaultValue;
+ }
+
+ long[] longValues = new long[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ longValues[i] = getLong(values[i]);
+ }
+
+ return longValues;
+ }
+
+ public static short getShort(Serializable value) {
+ return getShort(value, DEFAULT_SHORT);
+ }
+
+ public static short getShort(Serializable value, short defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static short getShort(String value) {
+ return getShort(value, DEFAULT_SHORT);
+ }
+
+ public static short getShort(String value, short defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static short[] getShortValues(Serializable value) {
+ return getShortValues(value, DEFAULT_SHORT_VALUES);
+ }
+
+ public static short[] getShortValues(
+ Serializable value, short[] defaultValue) {
+
+ Class> classObject = value.getClass();
+
+ if (classObject.isArray()) {
+ Class> componentType = classObject.getComponentType();
+
+ if (componentType.isAssignableFrom(String.class)) {
+ return getShortValues((String[])value, defaultValue);
+ }
+ else if (componentType.isAssignableFrom(Short.class)) {
+ return (short[])value;
+ }
+ }
+
+ return defaultValue;
+ }
+
+ public static short[] getShortValues(String[] values) {
+ return getShortValues(values, DEFAULT_SHORT_VALUES);
+ }
+
+ public static short[] getShortValues(
+ String[] values, short[] defaultValue) {
+
+ if (values == null) {
+ return defaultValue;
+ }
+
+ short[] shortValues = new short[values.length];
+
+ for (int i = 0; i < values.length; i++) {
+ shortValues[i] = getShort(values[i]);
+ }
+
+ return shortValues;
+ }
+
+ public static String getString(Serializable value) {
+ return getString(value, DEFAULT_STRING);
+ }
+
+ public static String getString(Serializable value, String defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ public static String getString(String value) {
+ return getString(value, DEFAULT_STRING);
+ }
+
+ public static String getString(String value, String defaultValue) {
+ return get(value, defaultValue);
+ }
+
+ private static int _parseInt(String value, int defaultValue) {
+ int length = value.length();
+
+ if (length <= 0) {
+ return defaultValue;
+ }
+
+ int pos = 0;
+ int limit = -Integer.MAX_VALUE;
+ boolean negative = false;
+
+ char c = value.charAt(0);
+
+ if (c < CharPool.NUMBER_0) {
+ if (c == CharPool.MINUS) {
+ limit = Integer.MIN_VALUE;
+ negative = true;
+ }
+ else if (c != CharPool.PLUS) {
+ return defaultValue;
+ }
+
+ if (length == 1) {
+ return defaultValue;
+ }
+
+ pos++;
+ }
+
+ int smallLimit = limit / 10;
+
+ int result = 0;
+
+ while (pos < length) {
+ if (result < smallLimit) {
+ return defaultValue;
+ }
+
+ c = value.charAt(pos++);
+
+ if ((c < CharPool.NUMBER_0) || (c > CharPool.NUMBER_9)) {
+ return defaultValue;
+ }
+
+ int number = c - CharPool.NUMBER_0;
+
+ result *= 10;
+
+ if (result < (limit + number)) {
+ return defaultValue;
+ }
+
+ result -= number;
+ }
+
+ if (negative) {
+ return result;
+ }
+ else {
+ return -result;
+ }
+ }
+
+ private static long _parseLong(String value, long defaultValue) {
+ int length = value.length();
+
+ if (length <= 0) {
+ return defaultValue;
+ }
+
+ int pos = 0;
+ long limit = -Long.MAX_VALUE;
+ boolean negative = false;
+
+ char c = value.charAt(0);
+
+ if (c < CharPool.NUMBER_0) {
+ if (c == CharPool.MINUS) {
+ limit = Long.MIN_VALUE;
+ negative = true;
+ }
+ else if (c != CharPool.PLUS) {
+ return defaultValue;
+ }
+
+ if (length == 1) {
+ return defaultValue;
+ }
+
+ pos++;
+ }
+
+ long smallLimit = limit / 10;
+
+ long result = 0;
+
+ while (pos < length) {
+ if (result < smallLimit) {
+ return defaultValue;
+ }
+
+ c = value.charAt(pos++);
+
+ if ((c < CharPool.NUMBER_0) || (c > CharPool.NUMBER_9)) {
+ return defaultValue;
+ }
+
+ int number = c - CharPool.NUMBER_0;
+
+ result *= 10;
+
+ if (result < (limit + number)) {
+ return defaultValue;
+ }
+
+ result -= number;
+ }
+
+ if (negative) {
+ return result;
+ }
+ else {
+ return -result;
+ }
+ }
+
+ private static short _parseShort(String value, short defaultValue) {
+ int i = _parseInt(value, defaultValue);
+
+ if ((i < Short.MIN_VALUE) || (i > Short.MAX_VALUE)) {
+ return defaultValue;
+ }
+
+ return (short)i;
+ }
+
+ private static String _trim(String value) {
+ value = value.trim();
+
+ int length = value.length();
+
+ StringBuilder sb = new StringBuilder(length);
+
+ for (int i = 0; i < length; i++) {
+ char c = value.charAt(i);
+
+ if ((Character.isDigit(c)) ||
+ ((c == CharPool.DASH) && (i == 0)) ||
+ (c == CharPool.PERIOD) || (c == CharPool.UPPER_CASE_E) ||
+ (c == CharPool.LOWER_CASE_E)) {
+
+ sb.append(c);
+ }
+ }
+
+ return sb.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/JavaProps.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/JavaProps.java
new file mode 100644
index 000000000..8e5badabd
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/JavaProps.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+// import com.liferay.portal.kernel.log.Log;
+// import com.liferay.portal.kernel.log.LogFactoryUtil;
+// import com.liferay.portal.kernel.log.LogUtil;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class JavaProps {
+
+ public static final double JAVA_CLASS_VERSION_JDK_4 = 48.0;
+
+ public static final double JAVA_CLASS_VERSION_JDK_5 = 49.0;
+
+ public static final double JAVA_CLASS_VERSION_JDK_6 = 50.0;
+
+ public static final double JAVA_CLASS_VERSION_JDK_7 = 51.0;
+
+ public static String getJavaClassPath() {
+ return _instance._javaClassPath;
+ }
+
+ public static double getJavaClassVersion() {
+ return _instance._javaClassVersion;
+ }
+
+ public static String getJavaRuntimeVersion() {
+ return _instance._javaRuntimeVersion;
+ }
+
+ public static double getJavaSpecificationVersion() {
+ return _instance._javaSpecificationVersion;
+ }
+
+ public static String getJavaVersion() {
+ return _instance._javaVersion;
+ }
+
+ public static String getJavaVmVersion() {
+ return _instance._javaVmVersion;
+ }
+
+ public static boolean isJDK4() {
+ if (JavaProps.getJavaClassVersion() >=
+ JavaProps.JAVA_CLASS_VERSION_JDK_4) {
+
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public static boolean isJDK5() {
+ if (JavaProps.getJavaClassVersion() >=
+ JavaProps.JAVA_CLASS_VERSION_JDK_5) {
+
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public static boolean isJDK6() {
+ if (JavaProps.getJavaClassVersion() >=
+ JavaProps.JAVA_CLASS_VERSION_JDK_6) {
+
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public static boolean isJDK7() {
+ if (JavaProps.getJavaClassVersion() >=
+ JavaProps.JAVA_CLASS_VERSION_JDK_7) {
+
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ private JavaProps() {
+ _javaClassPath = System.getProperty("java.class.path");
+ _javaClassVersion = Double.parseDouble(System.getProperty(
+ "java.class.version"));
+ _javaRuntimeVersion = System.getProperty("java.runtime.version");
+ _javaSpecificationVersion = Double.parseDouble(System.getProperty(
+ "java.specification.version"));
+ _javaVersion = System.getProperty("java.version");
+ _javaVmVersion = System.getProperty("java.vm.version");
+
+// LogUtil.debug(_log, System.getProperties());
+ }
+
+// private static Log _log = LogFactoryUtil.getLog(JavaProps.class);
+
+ private static JavaProps _instance = new JavaProps();
+
+ private String _javaClassPath;
+ private double _javaClassVersion;
+ private String _javaRuntimeVersion;
+ private double _javaSpecificationVersion;
+ private String _javaVersion;
+ private String _javaVmVersion;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/KeyValuePair.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/KeyValuePair.java
new file mode 100644
index 000000000..71934272a
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/KeyValuePair.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.Serializable;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class KeyValuePair implements Comparable, Serializable {
+
+ public KeyValuePair() {
+ this(null, null);
+ }
+
+ public KeyValuePair(String key, String value) {
+ _key = key;
+ _value = value;
+ }
+
+ public String getKey() {
+ return _key;
+ }
+
+ public void setKey(String key) {
+ _key = key;
+ }
+
+ public String getValue() {
+ return _value;
+ }
+
+ public void setValue(String value) {
+ _value = value;
+ }
+
+ public int compareTo(KeyValuePair kvp) {
+ return _key.compareTo(kvp.getKey());
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ KeyValuePair kvp = (KeyValuePair)obj;
+
+ String key = kvp.getKey();
+
+ if (_key.equals(key)) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public int hashCode() {
+ return _key.hashCode();
+ }
+
+ private String _key;
+ private String _value;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/ListWrapper.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/ListWrapper.java
new file mode 100644
index 000000000..040157c94
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/ListWrapper.java
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class ListWrapper implements List {
+
+ public ListWrapper(List list) {
+ _list = list;
+ }
+
+ public boolean add(E o) {
+ return _list.add(o);
+ }
+
+ public void add(int index, E element) {
+ _list.add(index, element);
+ }
+
+ public boolean addAll(Collection extends E> c) {
+ return _list.addAll(c);
+ }
+
+ public boolean addAll(int index, Collection extends E> c) {
+ return _list.addAll(index, c);
+ }
+
+ public void clear() {
+ _list.clear();
+ }
+
+ public boolean contains(Object o) {
+ return _list.contains(o);
+ }
+
+ public boolean containsAll(Collection> c) {
+ return _list.containsAll(c);
+ }
+
+ public E get(int index) {
+ return _list.get(index);
+ }
+
+ public int indexOf(Object o) {
+ return _list.indexOf(o);
+ }
+
+ public boolean isEmpty() {
+ return _list.isEmpty();
+ }
+
+ public Iterator iterator() {
+ return _list.iterator();
+ }
+
+ public int lastIndexOf(Object o) {
+ return _list.lastIndexOf(o);
+ }
+
+ public ListIterator listIterator() {
+ return _list.listIterator();
+ }
+
+ public ListIterator listIterator(int index) {
+ return _list.listIterator(index);
+ }
+
+ public boolean remove(Object o) {
+ return _list.remove(o);
+ }
+
+ public E remove(int index) {
+ return _list.remove(index);
+ }
+
+ public boolean removeAll(Collection> c) {
+ return _list.removeAll(c);
+ }
+
+ public boolean retainAll(Collection> c) {
+ return _list.retainAll(c);
+ }
+
+ public E set(int index, E element) {
+ return _list.set(index, element);
+ }
+
+ public int size() {
+ return _list.size();
+ }
+
+ public List subList(int fromIndex, int toIndex) {
+ return _list.subList(fromIndex, toIndex);
+ }
+
+ public Object[] toArray() {
+ return _list.toArray();
+ }
+
+ public T[] toArray(T[] a) {
+ return _list.toArray(a);
+ }
+
+ private List _list;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodCache.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodCache.java
new file mode 100644
index 000000000..9060eb28a
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodCache.java
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.lang.reflect.Method;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Michael C. Han
+ */
+public class MethodCache {
+
+ public static Method get(String className, String methodName)
+ throws ClassNotFoundException, NoSuchMethodException {
+
+ return get(null, null, className, methodName);
+ }
+
+ public static Method get(
+ String className, String methodName, Class>[] parameterTypes)
+ throws ClassNotFoundException, NoSuchMethodException {
+
+ return get(null, null, className, methodName, parameterTypes);
+ }
+
+ public static Method get(
+ Map> classesMap, Map methodsMap,
+ String className, String methodName)
+ throws ClassNotFoundException, NoSuchMethodException {
+
+ return get(className, methodName, new Class[0]);
+ }
+
+ public static Method get(
+ Map> classesMap, Map methodsMap,
+ String className, String methodName, Class>[] parameterTypes)
+ throws ClassNotFoundException, NoSuchMethodException {
+
+ MethodKey methodKey = new MethodKey(
+ className, methodName, parameterTypes);
+
+ return _instance._get(classesMap, methodsMap, methodKey);
+ }
+
+ public static Method get(MethodKey methodKey)
+ throws ClassNotFoundException, NoSuchMethodException {
+
+ return _instance._get(null, null, methodKey);
+ }
+
+ public static Method put(MethodKey methodKey, Method method) {
+ return _instance._put(methodKey, method);
+ }
+
+ private MethodCache() {
+ _classesMap = new HashMap>();
+ _methodsMap = new HashMap();
+ }
+
+ private Method _get(
+ Map> classesMap, Map methodsMap,
+ MethodKey methodKey)
+ throws ClassNotFoundException, NoSuchMethodException {
+
+ if (classesMap == null) {
+ classesMap = _classesMap;
+ }
+
+ if (methodsMap == null) {
+ methodsMap = _methodsMap;
+ }
+
+ Method method = methodsMap.get(methodKey);
+
+ if (method == null) {
+ String className = methodKey.getClassName();
+ String methodName = methodKey.getMethodName();
+ Class>[] parameterTypes = methodKey.getParameterTypes();
+
+ Class> classObj = classesMap.get(className);
+
+ if (classObj == null) {
+ Thread currentThread = Thread.currentThread();
+
+ ClassLoader contextClassLoader =
+ currentThread.getContextClassLoader();
+
+ classObj = contextClassLoader.loadClass(className);
+
+ classesMap.put(className, classObj);
+ }
+
+ method = classObj.getMethod(methodName, parameterTypes);
+
+ methodsMap.put(methodKey, method);
+ }
+
+ return method;
+ }
+
+ private Method _put(MethodKey methodKey, Method method) {
+ return _methodsMap.put(methodKey, method);
+ }
+
+ private static MethodCache _instance = new MethodCache();
+
+ private Map> _classesMap;
+ private Map _methodsMap;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodHandler.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodHandler.java
new file mode 100644
index 000000000..dbd144355
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodHandler.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.Serializable;
+
+import java.lang.reflect.Method;
+
+import java.util.Arrays;
+
+/**
+ * @author Shuyang Zhou
+ */
+public class MethodHandler implements Serializable {
+
+ public MethodHandler(Method method, Object... arguments) {
+ this(new MethodKey(method), arguments);
+ }
+
+ public MethodHandler(MethodKey methodKey, Object... arguments) {
+ _methodKey = methodKey;
+ _arguments = arguments;
+ }
+
+ public Object[] getArguments() {
+ Object[] arguments = new Object[_arguments.length];
+
+ System.arraycopy(_arguments, 0, arguments, 0, _arguments.length);
+
+ return arguments;
+ }
+
+ public Class>[] getArgumentsClasses() {
+ return _methodKey.getParameterTypes();
+ }
+
+ public String getClassName() {
+ return _methodKey.getClassName();
+ }
+
+ public MethodKey getMethodKey() {
+ return _methodKey;
+ }
+
+ public String getMethodName() {
+ return _methodKey.getMethodName();
+ }
+
+ public Object invoke(boolean newInstance) throws Exception {
+ Thread currentThread = Thread.currentThread();
+
+ ClassLoader contextClassLoader = currentThread.getContextClassLoader();
+
+ Object targetObject = null;
+
+ if (newInstance) {
+ Class> targetClass = contextClassLoader.loadClass(
+ getClassName());
+
+ targetObject = targetClass.newInstance();
+ }
+
+ return invoke(targetObject);
+ }
+
+ public Object invoke(Object target) throws Exception {
+ Method method = MethodCache.get(_methodKey);
+
+ return method.invoke(target, _arguments);
+ }
+
+ public String toString() {
+ StringBundler sb = new StringBundler(5);
+
+ sb.append("{arguments=");
+ sb.append(Arrays.toString(_arguments));
+ sb.append(", methodKey=");
+ sb.append(_methodKey);
+ sb.append("}");
+
+ return sb.toString();
+ }
+
+ private Object[] _arguments;
+ private MethodKey _methodKey;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodInvoker.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodInvoker.java
new file mode 100644
index 000000000..3a0dcc08a
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodInvoker.java
@@ -0,0 +1,261 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Brian Wing Shun Chan
+ * @author Harry Mark
+ * @author Shuyang Zhou
+ * @deprecated
+ */
+public class MethodInvoker {
+
+ public static Object invoke(MethodWrapper methodWrapper)
+ throws ClassNotFoundException, IllegalAccessException,
+ InstantiationException, InvocationTargetException,
+ NoSuchFieldException, NoSuchMethodException {
+
+ return invoke(methodWrapper, true);
+ }
+
+ public static Object invoke(
+ MethodWrapper methodWrapper, boolean newInstance)
+ throws ClassNotFoundException, IllegalAccessException,
+ InstantiationException, InvocationTargetException,
+ NoSuchFieldException, NoSuchMethodException {
+
+ Object targetObject = null;
+
+ if (newInstance) {
+ Thread currentThread = Thread.currentThread();
+
+ ClassLoader contextClassLoader =
+ currentThread.getContextClassLoader();
+
+ targetObject = contextClassLoader.loadClass(
+ methodWrapper.getClassName()).newInstance();
+ }
+
+ Object[] methodAndArguments = _lookupMethodAndArguments(
+ methodWrapper, targetObject);
+
+ Object returnObject = null;
+
+ if (methodAndArguments[0] != null) {
+ Method method = (Method)methodAndArguments[0];
+ Object[] arguments = (Object[])methodAndArguments[1];
+
+ returnObject = method.invoke(targetObject, arguments);
+ }
+
+ return returnObject;
+ }
+
+ public static Object invoke(
+ MethodWrapper methodWrapper, Object targetObject)
+ throws ClassNotFoundException, IllegalAccessException,
+ InvocationTargetException, NoSuchFieldException,
+ NoSuchMethodException {
+
+ Object[] methodAndArguments = _lookupMethodAndArguments(
+ methodWrapper, targetObject);
+
+ Object returnObject = null;
+
+ if (methodAndArguments[0] != null) {
+ Method method = (Method)methodAndArguments[0];
+ Object[] arguments = (Object[])methodAndArguments[1];
+
+ returnObject = method.invoke(targetObject, arguments);
+ }
+
+ return returnObject;
+ }
+
+ private static Object[] _lookupMethodAndArguments(
+ MethodWrapper methodWrapper, Object targetObject)
+ throws ClassNotFoundException, IllegalAccessException,
+ InvocationTargetException, NoSuchFieldException,
+ NoSuchMethodException {
+
+ Object[] methodAndArguments = new Object[2];
+
+ Thread currentThread = Thread.currentThread();
+
+ ClassLoader contextClassLoader = currentThread.getContextClassLoader();
+
+ String className = methodWrapper.getClassName();
+ String methodName = methodWrapper.getMethodName();
+ Object[] arguments = methodWrapper.getArguments();
+ String[] argumentClassNames = methodWrapper.getArgumentClassNames();
+
+ List> parameterTypes = new ArrayList>();
+
+ for (int i = 0; i < arguments.length; i++) {
+ if (arguments[i] == null) {
+ _log.error(
+ "Cannot invoke " + className + " " + methodName +
+ " on position " + i + " because it is null");
+ }
+
+ Class> argClass = null;
+
+ if (argumentClassNames != null) {
+ argClass = _primitiveTypeMap.get(argumentClassNames[i]);
+
+ if (argClass == null) {
+ argClass = Class.forName(
+ argumentClassNames[i], true, contextClassLoader);
+ }
+ }
+ else {
+ argClass = arguments[i].getClass();
+ }
+
+ if (ClassUtil.isSubclass(argClass, PrimitiveWrapper.class)) {
+ parameterTypes.add(
+ (Class>)argClass.getField("TYPE").get(arguments[i]));
+
+ MethodKey methodKey = new MethodKey(
+ argClass.getName(), "getValue");
+
+ Method method = MethodCache.get(methodKey);
+
+ arguments[i] = method.invoke(arguments[i], (Object[])null);
+ }
+ else if (arguments[i] instanceof NullWrapper) {
+ NullWrapper nullWrapper = (NullWrapper)arguments[i];
+
+ String wrappedClassName = nullWrapper.getClassName();
+
+ if (wrappedClassName.startsWith(StringPool.OPEN_BRACKET) &&
+ wrappedClassName.endsWith(StringPool.SEMICOLON)) {
+
+ wrappedClassName = wrappedClassName.substring(
+ 2, wrappedClassName.length() - 1);
+
+ Class> wrappedClass = contextClassLoader.loadClass(
+ wrappedClassName);
+
+ parameterTypes.add(
+ Array.newInstance(wrappedClass, 0).getClass());
+ }
+ else {
+ Class> wrappedClass = contextClassLoader.loadClass(
+ wrappedClassName);
+
+ parameterTypes.add(wrappedClass);
+ }
+
+ arguments[i] = null;
+ }
+ else {
+ parameterTypes.add(argClass);
+ }
+ }
+
+ MethodKey methodKey = null;
+
+ Method method = null;
+
+ try {
+ methodKey = new MethodKey(
+ methodWrapper.getClassName(), methodWrapper.getMethodName(),
+ parameterTypes.toArray(new Class[parameterTypes.size()]));
+
+ method = MethodCache.get(methodKey);
+ }
+ catch (NoSuchMethodException nsme) {
+ Class> classObject = null;
+
+ if (targetObject == null) {
+ classObject = contextClassLoader.loadClass(className);
+ }
+ else {
+ classObject = targetObject.getClass();
+ }
+
+ Method[] methods = classObject.getMethods();
+
+ for (int i = 0; i < methods.length; i++) {
+ Class>[] methodParameterTypes =
+ methods[i].getParameterTypes();
+
+ if (methods[i].getName().equals(methodName) &&
+ methodParameterTypes.length == parameterTypes.size()) {
+
+ boolean correctParams = true;
+
+ for (int j = 0; j < parameterTypes.size(); j++) {
+ Class> a = parameterTypes.get(j);
+ Class> b = methodParameterTypes[j];
+
+ if (!ClassUtil.isSubclass(a, b)) {
+ correctParams = false;
+
+ break;
+ }
+ }
+
+ if (correctParams) {
+ method = methods[i];
+
+ MethodCache.put(methodKey, method);
+
+ break;
+ }
+ }
+ }
+
+ if (method == null) {
+ throw nsme;
+ }
+ }
+
+ methodAndArguments[0] = method;
+ methodAndArguments[1] = arguments;
+
+ return methodAndArguments;
+ }
+
+ private static Log _log = LogFactoryUtil.getLog(MethodInvoker.class);
+
+ private static Map> _primitiveTypeMap =
+ new HashMap>();
+
+ static {
+ _primitiveTypeMap.put("char", char.class);
+ _primitiveTypeMap.put("boolean", boolean.class);
+ _primitiveTypeMap.put("byte", byte.class);
+ _primitiveTypeMap.put("double", double.class);
+ _primitiveTypeMap.put("float", float.class);
+ _primitiveTypeMap.put("int", int.class);
+ _primitiveTypeMap.put("long", long.class);
+ _primitiveTypeMap.put("short", short.class);
+ }
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodKey.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodKey.java
new file mode 100644
index 000000000..cf16a6438
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodKey.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.Serializable;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author Brian Wing Shun Chan
+ * @author Shuyang Zhou
+ */
+public class MethodKey implements Serializable {
+
+ public MethodKey(Method method) {
+ this(
+ method.getDeclaringClass().getName(), method.getName(),
+ method.getParameterTypes());
+ }
+
+ public MethodKey(
+ String className, String methodName, Class>... parameterTypes) {
+
+ _className = className;
+ _methodName = methodName;
+ _parameterTypes = parameterTypes;
+ }
+
+ public MethodKey(
+ String className, String methodName, String[] parameterTypeNames)
+ throws ClassNotFoundException {
+
+ _className = className;
+ _methodName = methodName;
+
+ _parameterTypes = new Class[parameterTypeNames.length];
+
+ for (int i = 0; i < parameterTypeNames.length; i++) {
+ String parameterTypeName = parameterTypeNames[i];
+
+ _parameterTypes[i] = Class.forName(parameterTypeName);
+ }
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ MethodKey methodKey = (MethodKey)obj;
+
+ if (toString().equals(methodKey.toString())) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public String getClassName() {
+ return _className;
+ }
+
+ public String getMethodName() {
+ return _methodName;
+ }
+
+ public Class>[] getParameterTypes() {
+ return _parameterTypes;
+ }
+
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ public String toString() {
+ return _toString();
+ }
+
+ private String _toString() {
+ if (_toString == null) {
+ StringBundler sb = new StringBundler();
+
+ sb.append(_className);
+ sb.append(_methodName);
+
+ if ((_parameterTypes != null) && (_parameterTypes.length > 0)) {
+ sb.append(StringPool.DASH);
+
+ for (Class> parameterType : _parameterTypes) {
+ sb.append(parameterType.getName());
+ }
+ }
+
+ _toString = sb.toString();
+ }
+
+ return _toString;
+ }
+
+ private String _className;
+ private String _methodName;
+ private Class>[] _parameterTypes;
+ private String _toString;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodWrapper.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodWrapper.java
new file mode 100644
index 000000000..2a4be0b63
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/MethodWrapper.java
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.Serializable;
+
+import java.lang.reflect.Method;
+
+import java.util.Arrays;
+
+/**
+ * @author Brian Wing Shun Chan
+ * @deprecated
+ */
+public class MethodWrapper implements Serializable {
+
+ public MethodWrapper(String className, String methodName) {
+ this(className, methodName, new Object[0]);
+ }
+
+ public MethodWrapper(String className, String methodName, Object argument) {
+ this(className, methodName, new Object[] {argument});
+ }
+
+ public MethodWrapper(
+ String className, String methodName, Object[] arguments) {
+
+ _className = className;
+ _methodName = methodName;
+ _arguments = arguments;
+ }
+
+ public MethodWrapper(Method method, Object[] arguments) {
+ this(method.getDeclaringClass().getName(), method.getName(), arguments);
+
+ _argumentClassNames = new String[arguments.length];
+
+ Class>[] parameterTypes = method.getParameterTypes();
+
+ for (int i = 0; i < parameterTypes.length; i++) {
+ _argumentClassNames[i] = parameterTypes[i].getName();
+ }
+ }
+
+ public String getClassName() {
+ return _className;
+ }
+
+ public String getMethodName() {
+ return _methodName;
+ }
+
+ /**
+ * @deprecated Use getArguments.
+ */
+ public Object[] getArgs() {
+ return getArguments();
+ }
+
+ public String[] getArgumentClassNames() {
+ return _argumentClassNames;
+ }
+
+ public Object[] getArguments() {
+ Object[] arguments = new Object[_arguments.length];
+
+ System.arraycopy(_arguments, 0, arguments, 0, _arguments.length);
+
+ return arguments;
+ }
+
+ public String toString() {
+ StringBundler sb = new StringBundler(9);
+
+ sb.append("{className=");
+ sb.append(_className);
+ sb.append(", methodName=");
+ sb.append(_methodName);
+
+ if (_argumentClassNames != null) {
+ sb.append(", argumentClassNames=");
+ sb.append(Arrays.toString(_argumentClassNames));
+ }
+
+ sb.append(", arguments=");
+ sb.append(Arrays.toString(_arguments));
+ sb.append("}");
+
+ return sb.toString();
+ }
+
+ private String _className;
+ private String _methodName;
+ private String[] _argumentClassNames;
+ private Object[] _arguments;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/NullWrapper.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/NullWrapper.java
new file mode 100644
index 000000000..5c883126c
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/NullWrapper.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.Serializable;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class NullWrapper implements Serializable {
+
+ public NullWrapper(String className) {
+ _className = className;
+ }
+
+ public String getClassName() {
+ return _className;
+ }
+
+ private String _className;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PortalClassInvoker.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PortalClassInvoker.java
new file mode 100644
index 000000000..bdbbe5f95
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PortalClassInvoker.java
@@ -0,0 +1,229 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * @author Brian Wing Shun Chan
+ * @author Shuyang Zhou
+ */
+public class PortalClassInvoker {
+
+ public static Object invoke(
+ boolean newInstance, MethodKey methodKey, Object... arguments)
+ throws Exception {
+
+ Thread currentThread = Thread.currentThread();
+
+ ClassLoader contextClassLoader = currentThread.getContextClassLoader();
+
+ try {
+ currentThread.setContextClassLoader(
+ PortalClassLoaderUtil.getClassLoader());
+
+ MethodHandler methodHandler = new MethodHandler(
+ methodKey, arguments);
+
+ return methodHandler.invoke(newInstance);
+ }
+ catch (InvocationTargetException ite) {
+ throw (Exception)ite.getCause();
+ }
+ finally {
+ currentThread.setContextClassLoader(contextClassLoader);
+ }
+ }
+
+ public static Object invoke(
+ boolean newInstance, String className, String methodName,
+ String[] parameterTypeNames, Object... arguments)
+ throws Exception {
+
+ Thread currentThread = Thread.currentThread();
+
+ ClassLoader contextClassLoader = currentThread.getContextClassLoader();
+
+ try {
+ currentThread.setContextClassLoader(
+ PortalClassLoaderUtil.getClassLoader());
+
+ MethodKey methodKey = new MethodKey(
+ className, methodName, parameterTypeNames);
+
+ MethodHandler methodHandler = new MethodHandler(
+ methodKey, arguments);
+
+ return methodHandler.invoke(newInstance);
+ }
+ catch (InvocationTargetException ite) {
+ throw (Exception)ite.getCause();
+ }
+ finally {
+ currentThread.setContextClassLoader(contextClassLoader);
+ }
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(String className, String methodName)
+ throws Exception {
+
+ return invoke(className, methodName, new Object[] {});
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(String className, String methodName, Object arg)
+ throws Exception {
+
+ return invoke(className, methodName, new Object[] {arg});
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object arg1, Object arg2)
+ throws Exception {
+
+ return invoke(className, methodName, new Object[] {arg1, arg2});
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object arg1, Object arg2,
+ Object arg3)
+ throws Exception {
+
+ return invoke(className, methodName, new Object[] {arg1, arg2, arg3});
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object[] args)
+ throws Exception {
+
+ return invoke(className, methodName, args, true);
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, boolean newInstance)
+ throws Exception {
+
+ return invoke(className, methodName, new Object[] {}, newInstance);
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object arg,
+ boolean newInstance)
+ throws Exception {
+
+ return invoke(className, methodName, new Object[] {arg}, newInstance);
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object arg1, Object arg2,
+ boolean newInstance)
+ throws Exception {
+
+ return invoke(
+ className, methodName, new Object[] {arg1, arg2}, newInstance);
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object arg1, Object arg2,
+ Object arg3, boolean newInstance)
+ throws Exception {
+
+ return invoke(
+ className, methodName, new Object[] {arg1, arg2, arg3},
+ newInstance);
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object arg1, Object arg2,
+ Object arg3, Object arg4, boolean newInstance)
+ throws Exception {
+
+ return invoke(
+ className, methodName, new Object[] {arg1, arg2, arg3, arg4},
+ newInstance);
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object arg1, Object arg2,
+ Object arg3, Object arg4, Object arg5, boolean newInstance)
+ throws Exception {
+
+ return invoke(
+ className, methodName, new Object[] {arg1, arg2, arg3, arg4, arg5},
+ newInstance);
+ }
+
+ /**
+ * @deprecated
+ */
+ public static Object invoke(
+ String className, String methodName, Object[] args,
+ boolean newInstance)
+ throws Exception {
+
+ Thread currentThread = Thread.currentThread();
+
+ ClassLoader contextClassLoader = currentThread.getContextClassLoader();
+
+ try {
+ currentThread.setContextClassLoader(
+ PortalClassLoaderUtil.getClassLoader());
+
+ MethodWrapper methodWrapper = new MethodWrapper(
+ className, methodName, args);
+
+ return MethodInvoker.invoke(methodWrapper, newInstance);
+ }
+ catch (InvocationTargetException ite) {
+ throw (Exception)ite.getCause();
+ }
+ finally {
+ currentThread.setContextClassLoader(contextClassLoader);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PortalClassLoaderUtil.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PortalClassLoaderUtil.java
new file mode 100644
index 000000000..84bc08a8f
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PortalClassLoaderUtil.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class PortalClassLoaderUtil {
+
+ public static ClassLoader getClassLoader() {
+ return _classLoader;
+ }
+
+ public static void setClassLoader(ClassLoader contextClassLoader) {
+ if (ServerDetector.isJOnAS() && JavaProps.isJDK6()) {
+ _classLoader = new URLClassLoader(new URL[0], contextClassLoader);
+ }
+ else {
+ _classLoader = contextClassLoader;
+ }
+ }
+
+ private static ClassLoader _classLoader;
+
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PrimitiveWrapper.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PrimitiveWrapper.java
new file mode 100644
index 000000000..7a2d28b74
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/PrimitiveWrapper.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.io.Serializable;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class PrimitiveWrapper implements Serializable {
+}
\ No newline at end of file
diff --git a/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/Randomizer.java b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/Randomizer.java
new file mode 100644
index 000000000..1e9ab75ad
--- /dev/null
+++ b/tools-ng/common/webxml-mergetool/src/com/liferay/portal/kernel/util/Randomizer.java
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ */
+
+package com.liferay.portal.kernel.util;
+
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * @author Brian Wing Shun Chan
+ */
+public class Randomizer extends Random {
+
+ public static Randomizer getInstance() {
+ return _instance;
+ }
+
+ public Randomizer() {
+ super();
+ }
+
+ public Randomizer(long seed) {
+ super(seed);
+ }
+
+ public int[] nextInt(int n, int size) {
+ if (size > n) {
+ size = n;
+ }
+
+ Set set = new LinkedHashSet();
+
+ for (int i = 0; i < size; i++) {
+ while (true) {
+ Integer value = new Integer(nextInt(n));
+
+ if (!set.contains(value)) {
+ set.add(value);
+
+ break;
+ }
+ }
+ }
+
+ int[] array = new int[set.size()];
+
+ Iterator itr = set.iterator();
+
+ for (int i = 0; i < array.length; i++) {
+ array[i] = itr.next().intValue();
+ }
+
+ return array;
+ }
+
+ public void randomize(char array[]) {
+ int length = array.length;
+
+ for (int i = 0; i < length - 1; i++) {
+ int x = nextInt(length);
+ char y = array[i];
+
+ array[i] = array[i + x];
+ array[i + x] = y;
+
+ length--;
+ }
+ }
+
+ public void randomize(int array[]) {
+ int length = array.length;
+
+ for (int i = 0; i < length - 1; i++) {
+ int x = nextInt(length);
+ int y = array[i];
+
+ array[i] = array[i + x];
+ array[i + x] = y;
+
+ length--;
+ }
+ }
+
+ public void randomize(List
+
var builder = new WebXMLBuilder(originalWebXML, customWebXML, mergedWebXML);
+
diff --git a/tools-ng/ecdc/scriptlib/build-ccm.xml b/tools-ng/ecdc/scriptlib/build-ccm.xml
index 5025c403e..ad4dfe696 100644
--- a/tools-ng/ecdc/scriptlib/build-ccm.xml
+++ b/tools-ng/ecdc/scriptlib/build-ccm.xml
@@ -104,8 +104,7 @@
-
-
+