You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ah...@apache.org on 2014/04/25 07:34:13 UTC
[15/51] [partial] BlazeDS Donation from Adobe Systems Inc
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/log/Logger.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/log/Logger.java b/modules/common/src/flex/messaging/log/Logger.java
new file mode 100755
index 0000000..e8f622f
--- /dev/null
+++ b/modules/common/src/flex/messaging/log/Logger.java
@@ -0,0 +1,402 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.log;
+
+import flex.messaging.util.PrettyPrinter;
+import flex.messaging.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * The <code>Logger</code> class is used to log out information. It provides named
+ * methods to log information out at the desired level. Each <code>Logger</code>
+ * will log information out for a log category that is settable.
+ *
+ * @exclude
+ */
+public class Logger
+{
+ /**
+ * The category this logger send messages for.
+ */
+ private volatile String category;
+
+ /**
+ * The list of targets that this logger will dispatch log events to.
+ */
+ private final ArrayList targets;
+
+ /**
+ * Constructs a <code>Logger</code> instance that will log
+ * information out to the specified category.
+ *
+ * @param category The category to log information for.
+ */
+ public Logger(String category)
+ {
+ this.category = category;
+ targets = new ArrayList();
+ }
+
+ /**
+ * Returns the category this <code>Logger</code> logs information for.
+ *
+ * @return The category this <code>Logger</code> logs information for.
+ */
+ public String getCategory()
+ {
+ return category;
+ }
+
+ /**
+ * Determines whether the <code>Logger</code> has at least one target.
+ *
+ * @return True if the <code>Logger</code> has one or more targets.
+ */
+ public boolean hasTarget()
+ {
+ synchronized (targets)
+ {
+ return !targets.isEmpty();
+ }
+ }
+ /**
+ * Adds a <code>Target</code> that will format and output log events
+ * generated by this <code>Logger</code>.
+ *
+ * @param target The <code>Target</code> to add.
+ */
+ void addTarget(Target target)
+ {
+ synchronized (targets)
+ {
+ if (!targets.contains(target))
+ targets.add(target);
+ }
+ }
+
+ /**
+ * Removes a <code>Target</code> from this <code>Logger</code>.
+ *
+ * @param target The <code>Target</code> to remove.
+ */
+ void removeTarget(Target target)
+ {
+ synchronized (targets)
+ {
+ targets.remove(target);
+ }
+ }
+
+ /*
+ * DEBUG
+ */
+ /**
+ * Logs out a debug message.
+ *
+ * @param message The message to log.
+ */
+ public void debug(String message)
+ {
+ log(LogEvent.DEBUG, message, null, null);
+ }
+
+ /**
+ * Logs out a debug message associated with a <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void debug(String message, Throwable t)
+ {
+ log(LogEvent.DEBUG, message, null, t);
+ }
+
+ /**
+ * Logs out a debug message supporting positional parameter substitutions.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ */
+ public void debug(String message, Object[] parameters)
+ {
+ log(LogEvent.DEBUG, message, parameters, null);
+ }
+
+ /**
+ * Logs out a debug message supporting positional parameter substitutions and an
+ * associated <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void debug(String message, Object[] parameters, Throwable t)
+ {
+ log(LogEvent.DEBUG, message, parameters, t);
+ }
+
+ /*
+ * INFO
+ */
+ /**
+ * Logs out an info message.
+ *
+ * @param message The message to log.
+ */
+ public void info(String message)
+ {
+ log(LogEvent.INFO, message, null, null);
+ }
+
+ /**
+ * Logs out an info message associated with a <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void info(String message, Throwable t)
+ {
+ log(LogEvent.INFO, message, null, t);
+ }
+
+ /**
+ * Logs out an info message supporting positional parameter substitutions.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ */
+ public void info(String message, Object[] parameters)
+ {
+ log(LogEvent.INFO, message, parameters, null);
+ }
+
+ /**
+ * Logs out an info message supporting positional parameter substitutions and an
+ * associated <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void info(String message, Object[] parameters, Throwable t)
+ {
+ log(LogEvent.INFO, message, parameters, t);
+ }
+
+ /*
+ * WARN
+ */
+ /**
+ * Logs out a warn message.
+ *
+ * @param message The message to log.
+ */
+ public void warn(String message)
+ {
+ log(LogEvent.WARN, message, null, null);
+ }
+
+ /**
+ * Logs out a warn message associated with a <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void warn(String message, Throwable t)
+ {
+ log(LogEvent.WARN, message, null, t);
+ }
+
+ /**
+ * Logs out a warn message supporting positional parameter substitutions.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ */
+ public void warn(String message, Object[] parameters)
+ {
+ log(LogEvent.WARN, message, parameters, null);
+ }
+
+ /**
+ * Logs out a warn message supporting positional parameter substitutions and an
+ * associated <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void warn(String message, Object[] parameters, Throwable t)
+ {
+ log(LogEvent.WARN, message, parameters, t);
+ }
+
+ /*
+ * ERROR
+ */
+ /**
+ * Logs out an error message.
+ *
+ * @param message The message to log.
+ */
+ public void error(String message)
+ {
+ log(LogEvent.ERROR, message, null, null);
+ }
+
+ /**
+ * Logs out an error message associated with a <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void error(String message, Throwable t)
+ {
+ log(LogEvent.ERROR, message, null, t);
+ }
+
+ /**
+ * Logs out an error message supporting positional parameter substitutions.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ */
+ public void error(String message, Object[] parameters)
+ {
+ log(LogEvent.ERROR, message, parameters, null);
+ }
+
+ /**
+ * Logs out an error message supporting positional parameter substitutions and an
+ * associated <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void error(String message, Object[] parameters, Throwable t)
+ {
+ log(LogEvent.ERROR, message, parameters, t);
+ }
+
+ /*
+ * FATAL
+ */
+ /**
+ * Logs out a fatal message.
+ *
+ * @param message The message to log.
+ */
+ public void fatal(String message)
+ {
+ log(LogEvent.FATAL, message, null, null);
+ }
+
+ /**
+ * Logs out a fatal message associated with a <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void fatal(String message, Throwable t)
+ {
+ log(LogEvent.FATAL, message, null, t);
+ }
+
+ /**
+ * Logs out a fatal message supporting positional parameter substitutions.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ */
+ public void fatal(String message, Object[] parameters)
+ {
+ log(LogEvent.FATAL, message, parameters, null);
+ }
+
+ /**
+ * Logs out a fatal message supporting positional parameter substitutions and an
+ * associated <code>Throwable</code>.
+ *
+ * @param message The message to log.
+ * @param parameters Parameters to substitute into the message.
+ * @param t The associated <code>Throwable</code>.
+ */
+ public void fatal(String message, Object[] parameters, Throwable t)
+ {
+ log(LogEvent.FATAL, message, parameters, t);
+ }
+
+ /**
+ * @exclude
+ * The methods named according to log level delegate to this method to log.
+ *
+ * @param level The log level.
+ * @param message The message to log.
+ * @param parameters Substitution parameters (may be null).
+ * @param t The associated <code>Throwable</code> (may be null).
+ */
+ public void log(short level, String message, Object[] parameters, Throwable t)
+ {
+ log(level, message, parameters, t, true);
+ }
+
+ /**
+ * @exclude
+ * Logs a passed message if its level verifies as high enough.
+ *
+ * @param level The log level.
+ * @param message The message to log.
+ * @param parameters Substitution parameters (may be null).
+ * @param t The associated <code>Throwable</code>.
+ * @param verifyLevel <code>true</code> to verify the log level; otherwise log without verifying the level.
+ */
+ public void log(short level, String message, Object[] parameters, Throwable t, boolean verifyLevel)
+ {
+ if (targets.size() > 0 && (!verifyLevel || (level >= Log.getTargetLevel())))
+ {
+ if (parameters != null)
+ {
+ PrettyPrinter prettyPrinter = Log.getPrettyPrinter();
+
+ // replace all of the parameters in the msg string
+ for(int i = 0; i < parameters.length; i++)
+ {
+ String replacement = parameters[i] != null ? prettyPrinter.prettify(parameters[i]) : "null";
+
+ //this guy runs into problems if the replacement has a \ or $ in it
+ //message = message.replaceAll("\\{" + i + "\\}", replacement);
+ message = StringUtils.substitute(message, "{" + i + "}", replacement);
+ }
+ }
+ LogEvent event = new LogEvent(this, message, level, t);
+ Target tgt;
+ synchronized (targets)
+ {
+ for (Iterator iter = targets.iterator(); iter.hasNext();)
+ {
+ tgt = (Target) iter.next();
+ if (!verifyLevel || (level >= tgt.getLevel()))
+ tgt.logEvent(event);
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/log/Target.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/log/Target.java b/modules/common/src/flex/messaging/log/Target.java
new file mode 100755
index 0000000..c5c8224
--- /dev/null
+++ b/modules/common/src/flex/messaging/log/Target.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.log;
+
+import java.util.List;
+
+import flex.messaging.config.ConfigMap;
+
+/**
+ * All logger target implementations within the logging framework must
+ * implement this interface. <code>Target</code> implementations receive log events
+ * and output information from these events to the appropriate output
+ * destination which may be a console, log file or some other custom
+ * destination.
+ */
+public interface Target
+{
+ /**
+ * Initializes the target with id and properties.
+ *
+ * @param id id for the target.
+ * @param properties ConfigMap of properties for the target.
+ */
+ void initialize(String id, ConfigMap properties);
+
+ /**
+ * Returns the category filters defined for the <code>Target</code>.
+ *
+ * @return The category filters defined for the <code>Target</code>.
+ */
+ List getFilters();
+
+ /**
+ * Sets the category filters that the <code>Target</code> will process
+ * log events for.
+ *
+ * @param value The category filters that the <code>Target</code> will process
+ */
+ void setFilters(List value);
+
+ /**
+ * Adds the category filteer that the <code>Target</code> will process
+ * log events for.
+ *
+ * @param value The new category filter to add to the <code>Target</code>'s list of filters.
+ */
+ void addFilter(String value);
+
+ /**
+ * Removes a category filter from the list of filters the <code>Target</code> will
+ * process log events for.
+ *
+ * @param value The category filter to remove from the <code>Target</code>'s list of filters.
+ */
+ void removeFilter(String value);
+
+ /**
+ * Returns the log level that the <code>Target</code> will process log
+ * events for. Log events at this level, or at a higher priority level
+ * will be processed.
+ *
+ * @return The log level that the <code>Target</code> will process log events for.
+ */
+ short getLevel();
+
+ /**
+ * Sets the log level that the <code>Target</code> will process log events
+ * for. Log events at this level, or at a higher priority level will be
+ * processed.
+ *
+ * @param value The log level that the <code>Target</code> will process log events for.
+ */
+ void setLevel(short value);
+
+ /**
+ * Adds a <code>Logger</code> whose category matches the filters list for
+ * the <code>Target</code>. The <code>Logger</code> will dispatch log events
+ * to this <code>Target</code> to be output.
+ *
+ * @param logger The <code>Logger</code> to add.
+ */
+ void addLogger(Logger logger);
+
+ /**
+ * Removes a <code>Logger</code> from the <code>Target</code>.
+ *
+ * @param logger The <code>Logger</code> to remove.
+ */
+ void removeLogger(Logger logger);
+
+ /**
+ * Logs a log event out to the <code>Target</code>s output destination,
+ * which may be the console or a log file.
+ *
+ * @param event The <code>LogEvent</code> containing the information to output.
+ */
+ void logEvent(LogEvent event);
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/BasicPrettyPrinter.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/BasicPrettyPrinter.java b/modules/common/src/flex/messaging/util/BasicPrettyPrinter.java
new file mode 100755
index 0000000..6abc550
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/BasicPrettyPrinter.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * Prettifies the representation of an Object as a String. Complex
+ * types are not traversed.
+ *
+ * @exclude
+ */
+public class BasicPrettyPrinter implements PrettyPrinter
+{
+ protected ObjectTrace trace;
+
+ public BasicPrettyPrinter()
+ {
+ }
+
+ /**
+ * Prettifies the representation of an Object as a String.
+ * <ul>
+ * <li>Simple types are simply toString'ed.</li>
+ * <li>XML strings are formatted with line feeds and indentations.</li>
+ * <li>Complex types report their class names.</li>
+ * <li>Collections, Maps and native Arrays also report their size/length.</li>
+ * </ul>
+ * @return A prettified version of an Object as a String.
+ */
+ public String prettify(Object o)
+ {
+ try
+ {
+ trace = new ObjectTrace();
+ internalPrettify(o);
+ return trace.toString();
+ }
+ catch (Throwable t)
+ {
+ return trace.toString();
+ }
+ finally
+ {
+ trace = null;
+ }
+ }
+
+ protected void internalPrettify(Object o)
+ {
+ if (o == null)
+ {
+ trace.writeNull();
+ }
+ else if (o instanceof String)
+ {
+ String string = (String)o;
+ if (string.startsWith("<?xml"))
+ {
+ trace.write(StringUtils.prettifyXML(string));
+ }
+ else
+ {
+ trace.write(string);
+ }
+ }
+ else if (o instanceof Number || o instanceof Boolean || o instanceof Date
+ || o instanceof Calendar || o instanceof Character)
+ {
+ trace.write(o);
+ }
+ else
+ {
+ prettifyComplexType(o);
+ }
+ }
+
+ protected void prettifyComplexType(Object o)
+ {
+ StringBuffer header = new StringBuffer();
+
+ if (o instanceof PrettyPrintable)
+ {
+ PrettyPrintable pp = (PrettyPrintable)o;
+ header.append(pp.toStringHeader());
+ }
+
+ Class c = o.getClass();
+ String className = c.getName();
+
+ if (o instanceof Collection)
+ {
+ header.append(className).append(" (Collection size:").append(((Collection)o).size()).append(")");
+ }
+ else if (o instanceof Map)
+ {
+ header.append(className).append(" (Map size:").append(((Map)o).size()).append(")");
+ }
+ else if (c.isArray() && c.getComponentType() != null)
+ {
+ Class componentType = c.getComponentType();
+ className = componentType.getName();
+ header.append(className).append("[] (Array length:").append(Array.getLength(o)).append(")");
+ }
+ else
+ {
+ header.append(className);
+ }
+
+ trace.startObject(header.toString());
+ trace.endObject();
+ }
+
+ /**
+ * If the definition of toString is not from java.lang.Object or any class in the
+ * java.util.* package then we consider it a custom implementation in which case
+ * we'll use it instead of introspecting the class.
+ *
+ * @param c The class to check for a custom toString definition.
+ * @return Whether this class declares a custom toString() method.
+ */
+ protected boolean hasCustomToStringMethod(Class c)
+ {
+ try
+ {
+ Method toStringMethod = c.getMethod("toString", (Class[])null);
+ Class declaringClass = toStringMethod.getDeclaringClass();
+ if (declaringClass != Object.class
+ && !declaringClass.getName().startsWith("java.util"))
+ {
+ return true;
+ }
+ }
+ catch (Throwable t)
+ {
+ }
+
+ return false;
+ }
+
+ public Object copy()
+ {
+ return new BasicPrettyPrinter();
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/ExceptionUtil.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/ExceptionUtil.java b/modules/common/src/flex/messaging/util/ExceptionUtil.java
new file mode 100755
index 0000000..f787859
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/ExceptionUtil.java
@@ -0,0 +1,246 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+/**
+ * @exclude
+ */
+public class ExceptionUtil
+{
+ /**
+ * List of no-arg methods that are known to return a wrapped throwable.
+ **/
+ public static String[] unwrapMethods = { "getRootCause", "getTargetException",
+ "getTargetError", "getException",
+ "getCausedByException", "getLinkedException" };
+
+ /**
+ * Get the wrapped Exception object from the Throwable object.
+ * @param t the Throwable object
+ * @return Throwable the wrapped exception object if any
+ */
+ public static Throwable wrappedException(Throwable t)
+ {
+ // Handle these statically since they are core to Java
+ return (t instanceof InvocationTargetException)?
+ ((InvocationTargetException)t).getTargetException() : getRootCauseWithReflection(t);
+ }
+
+ /**
+ * Get to the base exception (if any).
+ * @param t the Throwable object
+ * @return the base Exception object
+ */
+ public static Throwable baseException(Throwable t)
+ {
+ Throwable wrapped = wrappedException(t);
+ return wrapped != null? baseException(wrapped) : t;
+ }
+
+ /**
+ * Return the stack trace in a String.
+ * @param t the Throwable object
+ * @return String the String presentation of the Throwable object
+ */
+ public static String toString(Throwable t)
+ {
+ StringWriter strWrt = new StringWriter();
+ t.printStackTrace(new PrintWriter(strWrt));
+
+ return strWrt.toString();
+ }
+
+ /**
+ * Return the stack trace up to the first line that starts with prefix.
+ *
+ * <p>Example: ExceptionUtil.getStackTraceUpTo(exception, "jrunx.");</p>
+ * @param t the Throwable object
+ * @param prefix the prefix message that we are looking for
+ * @return String the String of stack trace lines till the prefix message is located
+ */
+ public static String getStackTraceUpTo(Throwable t, String prefix)
+ {
+ StringTokenizer tokens = new StringTokenizer(toString(t), "\n\r");
+ StringBuffer trace = new StringBuffer();
+ boolean done = false;
+
+ String lookingFor = "at " + prefix;
+ while (!done && tokens.hasMoreElements())
+ {
+ String token = tokens.nextToken();
+ if (token.indexOf(lookingFor) == -1)
+ trace.append(token);
+ else
+ done = true;
+ trace.append(StringUtils.NEWLINE);
+ }
+
+ return trace.toString();
+ }
+
+ /**
+ * return the top n lines of this stack trace.
+ *
+ * <p>Example: ExceptionUtil.getStackTraceLines(exception, 10);</p>
+ * @param t the Throwable object
+ * @param numLines number of lines we should trace down
+ * @return String the String of stack trace lines
+ */
+ public static String getStackTraceLines(Throwable t, int numLines)
+ {
+ StringTokenizer tokens = new StringTokenizer(toString(t), "\n\r");
+
+ StringBuffer trace = new StringBuffer();
+
+ for (int i=0; i<numLines; i++)
+ {
+ String token = tokens.nextToken();
+ trace.append(token);
+ trace.append(StringUtils.NEWLINE);
+ }
+
+ return trace.toString();
+ }
+
+ /**
+ * Return the "nth" method call from the stack trace of "t", where 0 is
+ * the top.
+ * @param t the Throwable object
+ * @param nth the line number of the message should we skip
+ * @return String the callAt String
+ */
+ public static String getCallAt(Throwable t, int nth)
+ {
+ StringTokenizer tokens = new StringTokenizer(toString(t), "\n\r");
+ try
+ {
+ // Skip the first line - the exception message
+ for(int i = 0; i <= nth; ++i)
+ tokens.nextToken();
+
+ // get the method name from the next token
+ String token = tokens.nextToken();
+ int index1 = token.indexOf(' ');
+ int index2 = token.indexOf('(');
+ StringBuffer call = new StringBuffer();
+ call.append(token.substring(index1 < 0 ? 0 : index1 + 1, index2 < 0 ? call.length() : index2));
+
+ int index3 = token.indexOf(':', index2 < 0 ? 0 : index2);
+ if(index3 >= 0)
+ {
+ int index4 = token.indexOf(')', index3);
+ call.append(token.substring(index3, index4 < 0 ? token.length() : index4));
+ }
+ return call.toString();
+ }
+ catch(NoSuchElementException e) {}
+
+ return "unknown";
+ }
+
+
+ /**
+ * Utility method for converting an exception into a string. This
+ * method unwinds all wrapped exceptions
+ * @param t The throwable exception
+ * @return The printable exception
+ */
+ public static String exceptionToString(Throwable t)
+ {
+ StringWriter sw = new StringWriter();
+ PrintWriter out = new PrintWriter(sw);
+
+ //print out the exception stack.
+ printExceptionStack(t, out, 0);
+ return sw.toString();
+ }
+
+ /**
+ * Utility method for converting an exception and all chained root causes into a
+ * string. Unlike <code>exceptionToString(Throwable)</code> which prints the chain
+ * from most nested root cause down to the top-level exception, this method prints
+ * from the top-level exception down to the most nested root cause.
+ *
+ * @param t The throwable exception.
+ * @return The printable exception.
+ */
+ public static String exceptionFollowedByRootCausesToString(Throwable t)
+ {
+ StringBuffer output = new StringBuffer();
+ Throwable root = t;
+ while (root != null)
+ {
+ output.append((root == t) ? ((root instanceof Exception) ? " Exception: " : " Error: ") : " Root cause: ");
+ output.append(ExceptionUtil.toString(root));
+ // Do not recurse if the root cause has already been printed; this will have happened if the root cause has
+ // been assigned to the current Throwable via initCause() or as a constructor argument.
+ Throwable cause = root.getCause();
+ root = ExceptionUtil.wrappedException(root);
+ if (cause == root)
+ break;
+ }
+ return output.toString();
+ }
+
+ /**
+ * Recursively prints out a stack of wrapped exceptions.
+ */
+ protected static void printExceptionStack(Throwable th, PrintWriter out, int depth){
+ //only print the stack depth if the depth is greater than 0
+ boolean printStackDepth = depth>0;
+
+ Throwable wrappedException = ExceptionUtil.wrappedException(th);
+ if (wrappedException != null)
+ {
+ printStackDepth = true;
+ printExceptionStack(wrappedException, out, depth + 1);
+ }
+
+ if(printStackDepth){
+ out.write("[" + depth + "]");
+ }
+
+ th.printStackTrace(out);
+ }
+
+ private static Throwable getRootCauseWithReflection(Throwable t)
+ {
+ for(int i = 0; i < unwrapMethods.length; i++)
+ {
+ Method m = null;
+
+ try
+ {
+ m = t.getClass().getMethod(unwrapMethods[i], (Class[])null);
+ return (Throwable) m.invoke(t, (Object[])null);
+ }
+ catch(Exception nsme)
+ {
+ // ignore
+ }
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/FileUtils.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/FileUtils.java b/modules/common/src/flex/messaging/util/FileUtils.java
new file mode 100755
index 0000000..8f7146a
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/FileUtils.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package flex.messaging.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @exclude
+ */
+public class FileUtils
+{
+ public static final String UTF_8 = "UTF-8";
+ public static final String UTF_16 = "UTF-16";
+
+ /**
+ * Sets a mark in the InputStream for 3 bytes to check for a BOM. If the BOM
+ * stands for UTF-8 encoded content then the stream will not be reset, otherwise
+ * for UTF-16 with a BOM or any other encoding situation the stream is reset to the
+ * mark (as for UTF-16 the parser will handle the BOM).
+ *
+ * @param in InputStream containing BOM and must support mark().
+ * @param default_encoding The default character set encoding. null or "" => system default
+ * @return The file character set encoding.
+ * @throws IOException
+ */
+ public static final String consumeBOM(InputStream in, String default_encoding) throws IOException
+ {
+ in.mark(3);
+
+ // Determine file encoding...
+ // ASCII - no header (use the supplied encoding)
+ // UTF8 - EF BB BF
+ // UTF16 - FF FE or FE FF (decoder chooses endian-ness)
+ if (in.read() == 0xef && in.read() == 0xbb && in.read() == 0xbf)
+ {
+ // UTF-8 reader does not consume BOM, so do not reset
+ if (System.getProperty("flex.platform.CLR") != null)
+ {
+ return "UTF8";
+ }
+ else
+ {
+ return UTF_8;
+ }
+ }
+ else
+ {
+ in.reset();
+ int b0 = in.read();
+ int b1 = in.read();
+ if (b0 == 0xff && b1 == 0xfe || b0 == 0xfe && b1 == 0xff)
+ {
+ in.reset();
+ // UTF-16 reader will consume BOM
+ if (System.getProperty("flex.platform.CLR") != null)
+ {
+ return "UTF16";
+ }
+ else
+ {
+ return UTF_16;
+ }
+ }
+ else
+ {
+ // no BOM found
+ in.reset();
+ if (default_encoding != null && default_encoding.length() != 0)
+ {
+ return default_encoding;
+ }
+ else
+ {
+ return System.getProperty("file.encoding");
+ }
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/LocaleUtils.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/LocaleUtils.java b/modules/common/src/flex/messaging/util/LocaleUtils.java
new file mode 100755
index 0000000..e398971
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/LocaleUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+import java.util.Locale;
+
+/**
+ * @exclude
+ */
+public class LocaleUtils
+{
+ /**
+ * Builds a <code>Locale</code> instance from the passed string. If the string
+ * is <code>null</code> this method will return the default locale for the JVM.
+ *
+ * @param locale The locale as a string.
+ * @return The Locale instance built from the passed string.
+ */
+ public static Locale buildLocale(String locale)
+ {
+ if (locale == null)
+ {
+ return Locale.getDefault();
+ }
+ else
+ {
+ int index = locale.indexOf('_');
+ if (index == -1)
+ {
+ return new Locale(locale);
+ }
+ String language = locale.substring(0, index);
+ String rest = locale.substring(index + 1);
+ index = rest.indexOf('_');
+ if (index == -1)
+ {
+ return new Locale(language, rest);
+ }
+ String country = rest.substring(0, index);
+ rest = rest.substring(index + 1);
+ return new Locale(language, country, rest);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/ObjectTrace.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/ObjectTrace.java b/modules/common/src/flex/messaging/util/ObjectTrace.java
new file mode 100755
index 0000000..6477086
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/ObjectTrace.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+import flex.messaging.log.Log;
+
+/**
+ * Simple utility to trace an Object graph out to a StringBuffer.
+ *
+ * Note that new lines are NOT added after the individual values
+ * in complex type properties.
+ *
+ * @exclude
+ */
+public class ObjectTrace
+{
+
+
+ /* This boolean is used for suppressing debug output for selected properties.
+ * The logger will check this before printing a property.
+ */
+ public boolean nextElementExclude;
+
+ public ObjectTrace()
+ {
+ buffer = new StringBuffer(4096);
+ }
+
+ public ObjectTrace(int bufferSize)
+ {
+ buffer = new StringBuffer(bufferSize);
+ }
+
+ public String toString()
+ {
+ return buffer.toString();
+ }
+
+ public void write(Object o)
+ {
+ if (m_nested <= 0)
+ buffer.append(indentString());
+
+ buffer.append(String.valueOf(o));
+ }
+
+ public void writeNull()
+ {
+ if (m_nested <= 0)
+ buffer.append(indentString());
+
+ buffer.append("null");
+ }
+
+ public void writeRef(int ref)
+ {
+ if (m_nested <= 0)
+ buffer.append(indentString());
+
+ buffer.append("(Ref #").append(ref).append(")");
+ }
+
+ public void writeString(String s)
+ {
+ if (m_nested <= 0)
+ buffer.append(indentString());
+
+ buffer.append("\"").append(s).append("\"");
+ }
+
+ public void startArray(String header)
+ {
+ if (header != null && header.length() > 0)
+ {
+ if (m_nested <= 0)
+ buffer.append(indentString());
+
+ buffer.append(header).append(newLine);
+ }
+
+ m_indent++;
+ m_nested++;
+ }
+
+ public void arrayElement(int index)
+ {
+ buffer.append(indentString()).append("[").append(index).append("] = ");
+ }
+
+ public void endArray()
+ {
+ m_indent--;
+ m_nested--;
+ }
+
+ public void startObject(String header)
+ {
+ if (header != null && header.length() > 0)
+ {
+ if (m_nested <= 0)
+ buffer.append(indentString());
+
+ buffer.append(header).append(newLine);
+ }
+
+ m_indent++;
+ m_nested++;
+ }
+
+ public void namedElement(String name)
+ {
+ if (Log.isExcludedProperty(name))
+ {
+ nextElementExclude = true;
+ }
+
+ buffer.append(indentString()).append(name).append(" = ");
+ }
+
+ public void endObject()
+ {
+ m_indent--;
+ m_nested--;
+ }
+
+ public void newLine()
+ {
+ boolean alreadyPadded = false;
+ int length = buffer.length();
+
+ if (length > 3)
+ {
+ String tail = buffer.substring(length - 3, length - 1); //Get last two chars in buffer
+ alreadyPadded = tail.equals(newLine);
+ }
+
+ if (!alreadyPadded)
+ buffer.append(newLine);
+ }
+
+ /**
+ * Uses the static member, m_indent to create a string of spaces of
+ * the appropriate indentation.
+ */
+ protected String indentString()
+ {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < m_indent; ++i)
+ {
+ sb.append(" ");
+ }
+ return sb.toString();
+ }
+
+ protected StringBuffer buffer;
+ protected int m_indent;
+ protected int m_nested;
+ public static String newLine = StringUtils.NEWLINE;
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/PrettyPrintable.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/PrettyPrintable.java b/modules/common/src/flex/messaging/util/PrettyPrintable.java
new file mode 100755
index 0000000..3c2933b
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/PrettyPrintable.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+/**
+ * Allows an Object to customize how it is pretty printed in
+ * logging/debugging output.
+ *
+ * @exclude
+ */
+public interface PrettyPrintable
+{
+ String toStringHeader();
+
+ String toStringCustomProperty(String name);
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/PrettyPrinter.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/PrettyPrinter.java b/modules/common/src/flex/messaging/util/PrettyPrinter.java
new file mode 100755
index 0000000..c4e86c0
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/PrettyPrinter.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+/**
+ * Implementations convert Object graphs to Strings for
+ * logging and debugging.
+ *
+ * @exclude
+ */
+public interface PrettyPrinter
+{
+ String prettify(Object o);
+
+ Object copy();
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/PropertyStringResourceLoader.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/PropertyStringResourceLoader.java b/modules/common/src/flex/messaging/util/PropertyStringResourceLoader.java
new file mode 100755
index 0000000..39f571d
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/PropertyStringResourceLoader.java
@@ -0,0 +1,379 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import flex.messaging.log.Log;
+import flex.messaging.log.Logger;
+import flex.messaging.log.LogCategories;
+
+/**
+ * Implementation of <code>ResourceLoader</code> that loads string resources
+ * from property files.
+ * <p>
+ * This class uses <code>MessageFormat</code> to perform substitutions
+ * within parameterized strings.
+ * </p>
+ *
+ * @author Seth Hodgson
+ * @see MessageFormat
+ * @exclude
+ */
+public class PropertyStringResourceLoader implements ResourceLoader
+{
+ // The property file bundle that contains localized error strings for BlazeDS.
+ public static final String PROPERTY_BUNDLE = "flex/messaging/errors";
+
+ // The property file bundle that contains localized error strings for BlazeDS
+ // code specific to vendors (eg. LoginCommands for specific application serves)
+ public static final String VENDORS_BUNDLE = "flex/messaging/vendors";
+
+ // The property file bundle that contains localized error strings for LCDS.
+ public static final String LCDS_PROPERTY_BUNDLE = "flex/data/errors";
+
+ // The category to write log entries under.
+ private static final String LOG_CATEGORY = LogCategories.RESOURCE;
+
+ // The property bundle names to use in string lookups.
+ private String[] propertyBundles;
+
+ // The default FDS locale.
+ private Locale defaultLocale;
+
+ // The set of locales that have strings loaded.
+ private Set loadedLocales = new TreeSet();
+
+ // A map of all loaded strings.
+ private Map strings = new HashMap();
+
+ // The logger for this instance.
+ private Logger logger;
+
+ /**
+ * Constructs a <code>PropertyStringResourceLoader</code> using the default
+ * property bundles specified by the <code>PROPERTY_BUNDLE</code> and
+ * <code>LCDS_PROPERTY_BUNDLE</code> fields.
+ */
+ public PropertyStringResourceLoader()
+ {
+ this(new String[] {PROPERTY_BUNDLE, LCDS_PROPERTY_BUNDLE});
+ }
+
+ /**
+ * Constructs a <code>PropertyStringResourceLoader</code> that will use the
+ * specified property bundle to use for string lookups.
+ *
+ * @param propertyBundle The property bundles to use for lookups.
+ */
+ public PropertyStringResourceLoader(String propertyBundle)
+ {
+ this(new String[] {propertyBundle});
+ }
+
+ /**
+ * Constructs a <code>PropertyStringResourceLoader</code> that will use the
+ * specified property bundles to use for string lookups.
+ *
+ * @param propertyBundles The list of the property bundles to use for lookups.
+ */
+ public PropertyStringResourceLoader(String[] propertyBundles)
+ {
+ this.propertyBundles = propertyBundles;
+ logger = Log.getLogger(LOG_CATEGORY);
+ }
+
+ // Implements flex.messaging.util.ResourceLoader.init; inherits javadoc specification.
+ public void init(Map properties)
+ {}
+
+ // Implements flex.messaging.util.ResourceLoader.getString; inherits javadoc specification.
+ public String getString(String key)
+ {
+ return getString(key, null, null);
+ }
+
+ // Implements flex.messaging.util.ResourceLoader.getString; inherits javadoc specification.
+ public String getString(String key, Object[] arguments)
+ {
+ return getString(key, null, arguments);
+ }
+
+ // Implements flex.messaging.util.ResourceLoader.getString; inherits javadoc specification.
+ public String getString(String key, Locale locale)
+ {
+ return getString(key, locale, null);
+ }
+
+ // Implements flex.messaging.util.ResourceLoader.getString; inherits javadoc specification.
+ public String getString(String key, Locale locale, Object[] arguments)
+ {
+ synchronized(strings)
+ {
+ if (defaultLocale == null)
+ {
+ defaultLocale = getDefaultLocale();
+ }
+ }
+ String value = null;
+ String stringKey = null;
+ String localeKey = (locale != null) ?
+ generateLocaleKey(locale) :
+ generateLocaleKey(defaultLocale);
+ String originalStringKey = generateStringKey(key, localeKey);
+ int trimIndex = 0;
+
+ /*
+ * Attempt to get a string for the target locale - fail back to less specific
+ * versions of the locale.
+ */
+ while (true)
+ {
+ loadStrings(localeKey);
+ stringKey = generateStringKey(key, localeKey);
+ synchronized(strings)
+ {
+ value = (String) strings.get(stringKey);
+ if (value != null)
+ {
+ if (!stringKey.equals(originalStringKey))
+ {
+ strings.put(originalStringKey, value);
+ }
+ return substituteArguments(value, arguments);
+ }
+ }
+ trimIndex = localeKey.lastIndexOf('_');
+ if (trimIndex != -1)
+ {
+ localeKey = localeKey.substring(0, trimIndex);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /*
+ * Attempt to get the string in our default locale if it is
+ * different than the requested locale.
+ */
+ if ((locale != null) && (!locale.equals(defaultLocale)))
+ {
+ localeKey = generateLocaleKey(defaultLocale);
+ stringKey = generateStringKey(key, localeKey);
+ synchronized(strings)
+ {
+ value = (String) strings.get(stringKey);
+ if (value != null)
+ {
+ strings.put(originalStringKey, value);
+ return substituteArguments(value, arguments);
+ }
+ }
+ }
+
+ // As a last resort, try to get a non-locale-specific string.
+ loadStrings("");
+ stringKey = generateStringKey(key, "");
+ synchronized(strings)
+ {
+ value = (String) strings.get(stringKey);
+ if (value != null)
+ {
+ strings.put(originalStringKey, value);
+ return substituteArguments(value, arguments);
+ }
+ }
+
+ // No string is available. Return a formatted missing string value.
+ return ("???" + key + "???");
+ }
+
+ /**
+ * Sets the default locale to be used when locating resources. The
+ * string will be converted into a Locale.
+ *
+ * @param locale The default locale to be used.
+ */
+ public void setDefaultLocale(String locale)
+ {
+ defaultLocale = LocaleUtils.buildLocale(locale);
+ }
+
+ /**
+ * Sets the default locale to be used when locating resources.
+ *
+ * @param locale The default locale to be used.
+ */
+ public void setDefaultLocale(Locale locale)
+ {
+ defaultLocale = locale;
+ }
+
+ /**
+ * The default locale to be used when locating resources.
+ * @return Locale the default Locale object
+ */
+ public Locale getDefaultLocale()
+ {
+ if (defaultLocale == null)
+ defaultLocale = Locale.getDefault();
+
+ return defaultLocale;
+ }
+
+ /**
+ * Loads localized strings for the specified locale from a property file.
+ *
+ * @param localeKey The locale to load strings for.
+ */
+ protected synchronized void loadStrings(String localeKey)
+ {
+ if (loadedLocales.contains(localeKey))
+ {
+ return;
+ }
+
+ if (propertyBundles != null)
+ {
+ for (int i = 0; i < propertyBundles.length; i++)
+ {
+ String propertyBundle = propertyBundles[i];
+ loadProperties(localeKey, propertyBundle);
+ }
+ }
+ }
+
+ protected InputStream loadFile(String filename)
+ {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ InputStream stream = loader.getResourceAsStream(filename);
+
+ // Try the properties file in our classloader too - just in case
+ if (stream == null)
+ {
+ stream = PropertyStringResourceLoader.class.getClassLoader().getResourceAsStream(filename);
+ }
+
+ return stream;
+ }
+
+ // Helper method for loadStrings.
+ protected void loadProperties(String localeKey, String propertyBundle)
+ {
+ // Build the path to the target property file.
+ String filename = propertyBundle;
+ if (localeKey.length() > 0)
+ {
+ filename += "_" + localeKey;
+ }
+ filename += ".properties";
+ // Load the property file.
+ InputStream stream = loadFile(filename);
+
+ Properties props = new Properties();
+ if (stream != null)
+ {
+ try
+ {
+ props.load(stream);
+ }
+ catch (IOException ioe)
+ {
+ logger.warn("There was a problem reading the string resource property file '" + filename + "' stream.", ioe);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ logger.warn("The string resource property file '" + filename + "' contains a malformed Unicode escape sequence.", iae);
+ }
+ finally
+ {
+ try
+ {
+ stream.close();
+ }
+ catch (IOException ioe)
+ {
+ logger.warn("The string resource property file '" + filename + "' stream failed to close.", ioe);
+ }
+ }
+ }
+ else
+ {
+ logger.warn("The class loader could not locate the string resource property file '" + filename + "'. This may not be an issue if a property file is available for a less specific locale or the default locale.");
+ }
+ // Move strings into string cache.
+ if (props.size() > 0)
+ {
+ synchronized(strings)
+ {
+ Iterator iter = props.keySet().iterator();
+ while (iter.hasNext())
+ {
+ String key = (String) iter.next();
+ strings.put(generateStringKey(key, localeKey), props.getProperty(key));
+ }
+ }
+ }
+ }
+
+ /**
+ * Generates a locale cache key.
+ *
+ * @param locale The locale to generate a cache key for.
+ * @return The generated cache key.
+ */
+ private String generateLocaleKey(Locale locale)
+ {
+ return (locale == null) ? "" : locale.toString();
+ }
+
+ /**
+ * Generates a cache key for a string resource.
+ *
+ * @param key The string to generate a cache key for.
+ * @param locale The locale to retrieve the string for.
+ * @return The generated cache key for the string resource.
+ */
+ private String generateStringKey(String key, String locale)
+ {
+ return (key + "-" + locale);
+ }
+
+ /**
+ * Substitutes the specified arguments into a parameterized string.
+ *
+ * @param parameterized The string containing parameter tokens for substitution.
+ * @param arguments The arguments to substitute into the parameterized string.
+ * @return The resulting substituted string.
+ */
+ private String substituteArguments(String parameterized, Object[] arguments)
+ {
+ return MessageFormat.format(parameterized, arguments).trim();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/ResourceLoader.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/ResourceLoader.java b/modules/common/src/flex/messaging/util/ResourceLoader.java
new file mode 100755
index 0000000..0ea39b0
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/ResourceLoader.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * The root interface for classes that provide access to localized resources.
+ *
+ * @author Seth Hodgson
+ * @exclude
+ */
+public interface ResourceLoader
+{
+ /**
+ * Initializes the <code>ResourceLoader</code> using the specified properties.
+ *
+ * @param properties The initialization properties.
+ */
+ void init(Map properties);
+
+ /**
+ * Sets the default locale to be used when locating resources. The
+ * string will be converted into a Locale.
+ *
+ * @param locale The default locale to be used.
+ */
+ void setDefaultLocale(String locale);
+
+ /**
+ * Sets the default locale to be used when locating resources.
+ *
+ * @param locale The default locale to be used.
+ */
+ void setDefaultLocale(Locale locale);
+
+ /**
+ * The default locale to be used when locating resources.
+ *
+ * @return The default locale.
+ */
+ Locale getDefaultLocale();
+
+ /**
+ * Gets a string for the given key.
+ *
+ * @param key The key for the target string.
+ * @return The string for the given key.
+ */
+ String getString(String key);
+
+ /**
+ * Gets a parameterized string for the given key and substitutes
+ * the parameters using the passed array of arguments.
+ *
+ * @param key The key for the target string.
+ * @param arguments The arguments to substitute into the parameterized string.
+ * @return The substituted string for the given key.
+ * @exception IllegalArgumentException If the parameterized string is invalid,
+ * or if an argument in the <code>arguments</code> array
+ * is not of the type expected by the format element(s)
+ * that use it.
+ */
+ String getString(String key, Object[] arguments);
+
+ /**
+ * Gets a string for the given key and locale.
+ *
+ * @param key The key for the target string.
+ * @param locale The target locale for the string.
+ * @return The localized string for the given key.
+ */
+ String getString(String key, Locale locale);
+
+ /**
+ * Gets a parameterized string for the given key and locale and substitutes the
+ * parameters using the passed array of arguments.
+ *
+ * @param key The key for the target string.
+ * @param locale The target locale for the string.
+ * @param arguments The arguments to substitute into the parameterized string.
+ * @return The substituted localized string for the given key.
+ * @exception IllegalArgumentException If the parameterized string is invalid,
+ * or if an argument in the <code>arguments</code> array
+ * is not of the type expected by the format element(s)
+ * that use it.
+ */
+ String getString(String key, Locale locale, Object[] arguments);
+
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/StringUtils.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/StringUtils.java b/modules/common/src/flex/messaging/util/StringUtils.java
new file mode 100755
index 0000000..7eca7e6
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/StringUtils.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+/**
+ * @exclude
+ */
+public class StringUtils
+{
+ /**
+ * The String to use for an OS specific line separator.
+ */
+ public static final String NEWLINE = System.getProperty("line.separator");
+
+ public static String substitute(String str, String from, String to)
+ {
+ if (from == null || from.equals("") || to == null)
+ return str;
+
+ int index = str.indexOf(from);
+
+ if (index == -1)
+ return str;
+
+ StringBuffer buf = new StringBuffer(str.length());
+ int lastIndex = 0;
+
+ while (index != -1)
+ {
+ buf.append(str.substring(lastIndex, index));
+ buf.append(to);
+ lastIndex = index + from.length();
+ index = str.indexOf(from, lastIndex);
+ }
+
+ // add in last chunk
+ buf.append(str.substring(lastIndex));
+
+ return buf.toString();
+ }
+
+ public static boolean findMatchWithWildcard(char[] src, char[] pat)
+ {
+ if (src == null || pat == null)
+ return false;
+
+ // we consider an empty pattern to be a don't-match-anything pattern
+ if (pat.length == 0)
+ return false;
+
+ if (src.length == 0)
+ return (pat.length == 0 || (pat.length == 1 && (pat[0] == '*' || pat[0] == '?')));
+
+ boolean star = false;
+
+ int srcLen = src.length;
+ int patLen = pat.length;
+ int srcIdx = 0;
+ int patIdx = 0;
+
+ for (; srcIdx < srcLen; srcIdx++)
+ {
+ if (patIdx == patLen)
+ {
+ if (patLen < (srcLen - srcIdx))
+ patIdx = 0; //Start the search again
+ else
+ return false;
+ }
+
+ char s = src[srcIdx];
+ char m = pat[patIdx];
+
+ switch (m)
+ {
+ case '*':
+ // star on the end
+ if (patIdx == pat.length - 1)
+ return true;
+ star = true;
+ ++patIdx;
+ break;
+
+ case '?':
+ ++patIdx;
+ break;
+
+ default:
+ if (s != m)
+ {
+ if (!star)
+ {
+ if (patLen < (srcLen - srcIdx))
+ patIdx = 0; //Start the search again
+ else
+ return false;
+ }
+ }
+ else
+ {
+ star = false;
+ ++patIdx;
+ }
+ break;
+ }
+ }
+
+ if (patIdx < patLen)
+ {
+ //read off the rest of the pattern and make sure it's all wildcard
+ for (; patIdx < patLen; patLen++)
+ {
+ if (pat[patIdx] != '*')
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ return !star;
+ }
+
+ /**
+ * Returns a prettified version of the XML, with indentations and
+ * linefeeds. Returns the original string if there was an error.
+ * @param xml the xml string
+ * @return String the prettified xml string
+ */
+ public static String prettifyXML(String xml)
+ {
+ String result = xml;
+ try
+ {
+ StringReader reader = new StringReader(xml);
+ StringWriter writer = new StringWriter();
+ Transformer transformer =
+ TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.transform
+ (new StreamSource(reader), new StreamResult(writer));
+ writer.close();
+
+ result = writer.toString();
+ }
+ catch (TransformerFactoryConfigurationError error)
+ {
+ // Ignore.
+ }
+ catch (TransformerException error)
+ {
+ // Ignore.
+ }
+ catch (IOException error)
+ {
+ // Ignore.
+ }
+ return result;
+ }
+
+ /**
+ * Returns a prettified version of the string, or the original
+ * string if the operation is not possible.
+ * @param string the string to check
+ * @return String the prettified string
+ */
+ public static String prettifyString(String string)
+ {
+ String result = string;
+ if (string.startsWith("<?xml"))
+ {
+ result = prettifyXML(string);
+ }
+ return result;
+ }
+
+ /**
+ * Returns true if a string is null or empty.
+ * @param string the String to check
+ * @return boolean true if the string is an empty string
+ */
+ public static boolean isEmpty(String string)
+ {
+ return string == null || string.length() == 0;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/common/src/flex/messaging/util/UUIDUtils.java
----------------------------------------------------------------------
diff --git a/modules/common/src/flex/messaging/util/UUIDUtils.java b/modules/common/src/flex/messaging/util/UUIDUtils.java
new file mode 100755
index 0000000..8df82e3
--- /dev/null
+++ b/modules/common/src/flex/messaging/util/UUIDUtils.java
@@ -0,0 +1,330 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package flex.messaging.util;
+
+import java.util.Random;
+import java.util.UUID;
+
+public class UUIDUtils
+{
+ private static Random _weakRand = new Random();
+
+ /**
+ * The spec indicates that our time value should be based on 100 nano
+ * second increments but our time granularity is in milliseconds.
+ * The spec also says we can approximate the time by doing an increment
+ * when we dole out new ids in the same millisecond. We can fit 10,000
+ * 100 nanos into a single millisecond.
+ */
+ private static final int MAX_IDS_PER_MILLI = 10000;
+
+ /**
+ * Any given time-of-day value can only be used once; remember the last used
+ * value so we don't reuse them.
+ * <p>NOTE: this algorithm assumes the clock will not be turned back.
+ */
+ private static long lastUsedTOD = 0;
+ /** Counter to use when we need more than one id in the same millisecond. */
+ private static int numIdsThisMilli = 0;
+
+ /** Hex digits, used for padding UUID strings with random characters. */
+ private static final String alphaNum = "0123456789ABCDEF";
+
+ /** 4 bits per hex character. */
+ private static final int BITS_PER_DIGIT = 4;
+
+ private static final int BITS_PER_INT = 32;
+ private static final int BITS_PER_LONG = 64;
+ private static final int DIGITS_PER_INT = BITS_PER_INT / BITS_PER_DIGIT;
+ private static final int DIGITS_PER_LONG = BITS_PER_LONG / BITS_PER_DIGIT;
+
+ /**
+ * @private
+ */
+ private static char[] UPPER_DIGITS = new char[] {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+ };
+
+ /**
+ * Private constructor to prevent instances from being created.
+ */
+ private UUIDUtils()
+ {
+ }
+
+ /**
+ *
+ * Use the createUUID function when you need a unique string that you will
+ * use as a persistent identifier in a distributed environment. To a very
+ * high degree of certainty, this function returns a unique value; no other
+ * invocation on the same or any other system should return the same value.
+ *
+ * @return a Universally Unique Identifier (UUID)
+ * Proper Format: `XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
+ * where `X' stands for a hexadecimal digit (0-9 or A-F).
+ */
+ public static String createUUID()
+ {
+ return createUUID(false);
+ }
+
+ public static String createUUID(boolean secure) throws Error
+ {
+ Random rand = _weakRand;
+ if (secure)
+ throw new Error("Secure UUIDs not implemented");
+
+ StringBuffer s = new StringBuffer(36);
+
+ appendHexString(uniqueTOD(), false, 11, s);
+
+ // Just use random padding characters, but ensure that the high bit
+ // is set to eliminate chances of collision with an IEEE 802 address.
+ s.append( alphaNum.charAt( rand.nextInt(16) | 8 ) );
+
+ // Add random padding characters.
+ appendRandomHexChars(32 - s.length(), rand, s);
+
+ //insert dashes in proper position. so the format matches CF
+ s.insert(8,"-");
+ s.insert(13,"-");
+ s.insert(18,"-");
+ s.insert(23,"-");
+
+ return s.toString();
+ }
+
+ /**
+ * Converts a 128-bit UID encoded as a byte[] to a String representation.
+ * The format matches that generated by createUID. If a suitable byte[]
+ * is not provided, null is returned.
+ *
+ * @param ba byte[] 16 bytes in length representing a 128-bit UID.
+ *
+ * @return String representation of the UID, or null if an invalid
+ * byte[] is provided.
+ */
+ public static String fromByteArray(byte[] ba)
+ {
+ if (ba == null || ba.length != 16)
+ return null;
+
+ StringBuffer result = new StringBuffer(36);
+ for (int i = 0; i < 16; i++)
+ {
+ if (i == 4 || i == 6 || i == 8 || i == 10)
+ result.append('-');
+
+ result.append(UPPER_DIGITS[(ba[i] & 0xF0) >>> 4]);
+ result.append(UPPER_DIGITS[(ba[i] & 0x0F)]);
+ }
+ return result.toString();
+ }
+
+
+ /**
+ * A utility method to check whether a String value represents a
+ * correctly formatted UID value. UID values are expected to be
+ * in the format generated by createUID(), implying that only
+ * capitalized A-F characters in addition to 0-9 digits are
+ * supported.
+ *
+ * @param uid The value to test whether it is formatted as a UID.
+ *
+ * @return Returns true if the value is formatted as a UID.
+ */
+ public static boolean isUID(String uid)
+ {
+ if (uid == null || uid.length() != 36)
+ return false;
+
+ char[] chars = uid.toCharArray();
+ for (int i = 0; i < 36; i++)
+ {
+ char c = chars[i];
+
+ // Check for correctly placed hyphens
+ if (i == 8 || i == 13 || i == 18 || i == 23)
+ {
+ if (c != '-')
+ return false;
+ }
+ // We allow capital alpha-numeric hex digits only
+ else if (c < 48 || c > 70 || (c > 57 && c < 65))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Converts a UID formatted String to a byte[]. The UID must be in the
+ * format generated by createUID, otherwise null is returned.
+ *
+ * @param uid String representing a 128-bit UID.
+ *
+ * @return byte[] 16 bytes in length representing the 128-bits of the
+ * UID or null if the uid could not be converted.
+ */
+ public static byte[] toByteArray(String uid)
+ {
+ if (!isUID(uid))
+ return null;
+
+ byte[] result = new byte[16];
+ char[] chars = uid.toCharArray();
+ int r = 0;
+
+ for (int i = 0; i < chars.length; i++)
+ {
+ if (chars[i] == '-')
+ continue;
+ int h1 = Character.digit(chars[i], 16);
+ i++;
+ int h2 = Character.digit(chars[i], 16);
+ result[r++] = (byte)(((h1 << 4) | h2) & 0xFF);
+ }
+ return result;
+ }
+
+ private static void appendRandomHexChars(int n, Random rand, StringBuffer result)
+ {
+ int digitsPerInt = DIGITS_PER_INT;
+ while (n > 0)
+ {
+ int digitsToUse = Math.min(n, digitsPerInt);
+ n -= digitsToUse;
+ appendHexString(rand.nextInt(), true, digitsToUse, result);
+ }
+ }
+
+ private static void appendHexString
+ (long value, boolean prependZeroes, int nLeastSignificantDigits,
+ StringBuffer result)
+ {
+ int bitsPerDigit = BITS_PER_DIGIT;
+
+ long mask = (1L << bitsPerDigit) - 1;
+
+ if (nLeastSignificantDigits < DIGITS_PER_LONG)
+ {
+ // Clear the bits that we don't care about.
+ value &= (1L << (bitsPerDigit * nLeastSignificantDigits)) - 1;
+ }
+
+ // Reorder the sequence so that the first set of bits will become the
+ // last set of bits.
+ int i = 0;
+ long reorderedValue = 0;
+ if (value == 0)
+ {
+ // One zero is dumped.
+ i++;
+ }
+ else
+ {
+ do
+ {
+ reorderedValue = (reorderedValue << bitsPerDigit) | (value & mask);
+ value >>>= bitsPerDigit;
+ i++;
+ } while (value != 0);
+ }
+
+ if (prependZeroes)
+ {
+ for (int j = nLeastSignificantDigits - i; j > 0; j--)
+ {
+ result.append('0');
+ }
+ }
+
+
+ // Dump the reordered sequence, with the most significant character
+ // first.
+ for (; i > 0; i--)
+ {
+ result.append(alphaNum.charAt((int) (reorderedValue & mask)));
+ reorderedValue >>>= bitsPerDigit;
+ }
+ }
+
+ private static String createInsecureUUID()
+ {
+ StringBuffer s = new StringBuffer(36);
+
+ appendHexString(uniqueTOD(), false, 11, s);
+
+ // Just use random padding characters, but ensure that the high bit
+ // is set to eliminate chances of collision with an IEEE 802 address.
+ s.append( alphaNum.charAt( _weakRand.nextInt(16) | 8 ) );
+
+ // Add random padding characters.
+ appendRandomHexChars(32 - s.length(), _weakRand, s);
+
+ //insert dashes in proper position. so the format matches CF
+ s.insert(8,"-");
+ s.insert(13,"-");
+ s.insert(18,"-");
+ s.insert(23,"-");
+
+ return s.toString();
+ }
+
+ /**
+ * @return a time value, unique for calls to this method loaded by the same classloader.
+ */
+ private static synchronized long uniqueTOD()
+ {
+ long currentTOD = System.currentTimeMillis();
+
+ // Clock was set back... do not hang in this case waiting to catch up.
+ // Instead, rely on the random number part to differentiate the ids.
+ if (currentTOD < lastUsedTOD)
+ lastUsedTOD = currentTOD;
+
+ if (currentTOD == lastUsedTOD)
+ {
+ numIdsThisMilli++;
+ /*
+ * Fall back to the old technique of sleeping if we allocate
+ * too many ids in one time interval.
+ */
+ if (numIdsThisMilli >= MAX_IDS_PER_MILLI)
+ {
+ while ( currentTOD == lastUsedTOD )
+ {
+ try { Thread.sleep(1); } catch ( Exception interrupt ) { /* swallow, wake up */ }
+ currentTOD = System.currentTimeMillis();
+ }
+ lastUsedTOD = currentTOD;
+ numIdsThisMilli = 0;
+ }
+ }
+ else
+ {
+ // We have a new TOD, reset the counter
+ lastUsedTOD = currentTOD;
+ numIdsThisMilli = 0;
+ }
+
+ return lastUsedTOD * MAX_IDS_PER_MILLI + (long)numIdsThisMilli;
+ }
+}
http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/7a58369c/modules/core/AdobeInfo.xml
----------------------------------------------------------------------
diff --git a/modules/core/AdobeInfo.xml b/modules/core/AdobeInfo.xml
new file mode 100755
index 0000000..3504592
--- /dev/null
+++ b/modules/core/AdobeInfo.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+ <manifest version="1.0">
+ <versioninfo>
+ <build AdobeIPNumber="0000494"/>
+ </versioninfo>
+</manifest>
\ No newline at end of file