You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2017/04/16 22:32:34 UTC

[43/72] [abbrv] [partial] flex-blazeds git commit: - Major code scrub

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/FlexClientSettings.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/FlexClientSettings.java b/common/src/main/java/flex/messaging/config/FlexClientSettings.java
new file mode 100644
index 0000000..bba7e5a
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/FlexClientSettings.java
@@ -0,0 +1,134 @@
+/*
+ * 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.config;
+
+/**
+ *
+ */
+public class FlexClientSettings extends PropertiesSettings
+{
+    //--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     * Constructs a FlexClientSettings instance.
+     */
+    public FlexClientSettings()
+    {
+        // Empty for now.
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    // Properties
+    //
+    //--------------------------------------------------------------------------
+
+    private long timeoutMinutes = -1;
+
+    /**
+     * Returns the number of minutes before an idle FlexClient is timed out.
+     *
+     * @return The number of minutes before an idle FlexClient is timed out.
+     */
+    public long getTimeoutMinutes()
+    {
+        return timeoutMinutes;
+    }
+
+    /**
+     * Sets the number of minutes before an idle FlexClient is timed out.
+     *
+     * @param value The number of minutes before an idle FlexClient is timed out.
+     */
+    public void setTimeoutMinutes(long value)
+    {
+        timeoutMinutes = value;
+    }
+
+    private String flexClientOutboundQueueProcessorClassName;
+
+    /**
+     * Returns the name of the default <code>FlexClientOutboundQueueProcessorClass</code>.
+     *
+     * @return The the name of the  default <code>FlexClientOutboundQueueProcessorClass</code>.
+     */
+    public String getFlexClientOutboundQueueProcessorClassName()
+    {
+        return flexClientOutboundQueueProcessorClassName;
+    }
+
+    /**
+     * Sets the name of the default <code>FlexClientOutboundQueueProcessor</code>.
+     *
+     * @param flexClientOutboundQueueProcessorClassName The name of the default <code>FlexClientOutboundQueueProcessor</code>.
+     */
+    public void setFlexClientOutboundQueueProcessorClassName(String flexClientOutboundQueueProcessorClassName)
+    {
+        this.flexClientOutboundQueueProcessorClassName = flexClientOutboundQueueProcessorClassName;
+    }
+
+    private ConfigMap flexClientOutboundQueueProcessorProperties;
+
+    /**
+     * Returns the properties for the default <code>FlexClientOutboundQueueProcessor</code>.
+     *
+     * @return The properties for the default <code>FlexClientOutboundQueueProcessor</code>.
+     */
+    public ConfigMap getFlexClientOutboundQueueProcessorProperties()
+    {
+        return flexClientOutboundQueueProcessorProperties;
+    }
+
+    /**
+     * Sets the properties for the default <code>FlexClientOutboundQueueProcessor</code>.
+     *
+     * @param flexClientOutboundQueueProcessorProperties properties for the default
+     *                                                   <code>FlexClientOutboundQueueProcessor</code>
+     */
+    public void setFlexClientOutboundQueueProcessorProperties(ConfigMap flexClientOutboundQueueProcessorProperties)
+    {
+        this.flexClientOutboundQueueProcessorProperties = flexClientOutboundQueueProcessorProperties;
+    }
+    
+    private int reliableReconnectDurationMillis;
+    
+    public int getReliableReconnectDurationMillis()
+    {
+        return reliableReconnectDurationMillis;    
+    }
+    
+    public void setReliableReconnectDurationMillis(int value)
+    {
+        reliableReconnectDurationMillis = value;
+    }
+    
+    private int heartbeatIntervalMillis;
+    
+    public int getHeartbeatIntervalMillis()
+    {
+        return heartbeatIntervalMillis;
+    }
+    
+    public void setHeartbeatIntervalMillis(int value)
+    {
+        heartbeatIntervalMillis = value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/LocalFileResolver.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/LocalFileResolver.java b/common/src/main/java/flex/messaging/config/LocalFileResolver.java
new file mode 100644
index 0000000..04b623b
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/LocalFileResolver.java
@@ -0,0 +1,203 @@
+/*
+ * 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.config;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ *
+ */
+public class LocalFileResolver implements ConfigurationFileResolver
+{
+    public static final int CLIENT = 0;
+    public static final int SERVER = 1;
+    public static final int LIVECYCLE = 2;
+
+    private static final int ERR_MSG_INVALID_PATH_CLIENT = 11106;
+    private static final int ERR_MSG_INVALID_PATH_SERVER = 11108;
+    private static final int ERR_MSG_INVALID_PATH_LIVECYCLE = 11122;
+
+    private Stack configurationPathStack = new Stack();
+    int version = CLIENT;
+
+    public LocalFileResolver()
+    {
+    }
+
+    public LocalFileResolver(int version)
+    {
+        this.version = version;
+    }
+
+    public void setErrorMessage(ConfigurationException e, String path)
+    {
+        if (version == LIVECYCLE)
+        {
+            // Invalid location: ''{0}''. Please specify a valid LiveCycle Data Services Configuration file via the LiveCycle Admin UI.
+            e.setMessage(ERR_MSG_INVALID_PATH_LIVECYCLE, new Object[] {path});
+        }
+        else if (version == SERVER)
+        {
+            // Please specify a valid ''services.configuration.file'' in web.xml. You specified ''{0}''. This is not a valid file system path reachable via the app server and is also not a path to a resource in your J2EE application archive.
+            e.setMessage(ERR_MSG_INVALID_PATH_SERVER, new Object[]{path});
+        }
+        else
+        {
+            // Please specify a valid <services/> file path in flex-config.xml.
+            e.setMessage(ERR_MSG_INVALID_PATH_CLIENT);
+        }
+    }
+
+    public InputStream getConfigurationFile(String path)
+    {
+        File f = new File(path);
+        try
+        {
+            if (f != null && f.exists() && f.isAbsolute())
+            {
+                FileInputStream fin = new FileInputStream(f);
+                pushConfigurationFile(f.getParent());
+                return fin;
+            }
+            else
+            {
+                ConfigurationException e = new ConfigurationException();
+                setErrorMessage(e, path);
+                throw e;
+            }
+        }
+        catch (FileNotFoundException ex)
+        {
+            ConfigurationException e = new ConfigurationException();
+            setErrorMessage(e, path);
+            e.setRootCause(ex);
+            throw e;
+        }
+        catch (SecurityException se)
+        {
+            ConfigurationException e = new ConfigurationException();
+            setErrorMessage(e, path);
+            e.setRootCause(se);
+            throw e;
+        }
+    }
+
+    public InputStream getIncludedFile(String src)
+    {
+        String path = configurationPathStack.peek() + File.separator + src;
+        File f = new File(path);
+        try
+        {
+            if (f != null && f.exists() && f.isAbsolute())
+            {
+                FileInputStream fin = new FileInputStream(f);
+                pushConfigurationFile(f.getParent());
+                return fin;
+            }
+            else
+            {
+                // Please specify a valid include file. ''{0}'' is invalid.
+                ConfigurationException e = new ConfigurationException();
+                e.setMessage(11107, new Object[] {path});
+                throw e;
+            }
+        }
+        catch (FileNotFoundException ex)
+        {
+            // Please specify a valid include file. ''{0}'' is invalid.
+            ConfigurationException e = new ConfigurationException();
+            e.setMessage(11107, new Object[] {path});
+            e.setRootCause(ex);
+            throw e;
+        }
+        catch (SecurityException se)
+        {
+            // Please specify a valid include file. ''{0}'' is invalid.
+            ConfigurationException e = new ConfigurationException();
+            e.setMessage(11107, new Object[] {path});
+            e.setRootCause(se);
+            throw e;
+        }
+    }
+
+    public void popIncludedFile()
+    {
+        configurationPathStack.pop();
+    }
+
+    /**
+     * Returns the list of XML files (denoted by .xml extension) in the directory
+     * relative to the current configuration file.
+     *
+     * @param dir a directory relative to the current configuration file
+     * @return a (possibly empty) list of file names
+     */
+    public List getFiles(String dir)
+    {
+        List result = new ArrayList();
+        File f = new File(configurationPathStack.peek().toString(), dir);
+        if (f.exists() && f.isDirectory())
+        {
+            String[] xmlFiles = f.list(new FilenameFilter()
+            {
+                public boolean accept(File dir, String name)
+                {
+                    return name.endsWith(".xml");
+                }
+            });
+
+            // prepend the directory to each filename
+            for (int i = 0; i < xmlFiles.length; i++)
+            {
+                String file = xmlFiles[i];
+                result.add(dir +  File.separator + file);
+            }
+            return result;
+        }
+        else
+        {
+            // Please specify a valid include directory. ''{0}'' is invalid.
+            ConfigurationException e = new ConfigurationException();
+            e.setMessage(11113, new Object[]{dir});
+            throw e;
+        }
+    }
+
+    private void pushConfigurationFile(String topLevelPath)
+    {
+        configurationPathStack.push(topLevelPath);
+    }
+
+    public String getIncludedPath(String src)
+    {
+        return configurationPathStack.peek() + File.separator + src;
+    }
+
+    public long getIncludedLastModified(String src)
+    {
+        String path = configurationPathStack.peek() + File.separator + src;
+        File f = new File(path);
+        return f.lastModified();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/LoggingSettings.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/LoggingSettings.java b/common/src/main/java/flex/messaging/config/LoggingSettings.java
new file mode 100644
index 0000000..5fe26e1
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/LoggingSettings.java
@@ -0,0 +1,46 @@
+/*
+ * 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.config;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * A log maintains a series of Loggers for each logging category and
+ * Targets are established that listen for LogEvents on those Loggers.
+ *
+ *
+ */
+public class LoggingSettings extends PropertiesSettings
+{
+    private final List targets;
+
+    public LoggingSettings()
+    {
+        targets = new ArrayList();
+    }
+
+    public void addTarget(TargetSettings t)
+    {
+        targets.add(t);
+    }
+
+    public List getTargets()
+    {
+        return targets;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/LoginCommandSettings.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/LoginCommandSettings.java b/common/src/main/java/flex/messaging/config/LoginCommandSettings.java
new file mode 100644
index 0000000..2cc0ccd
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/LoginCommandSettings.java
@@ -0,0 +1,101 @@
+/*
+ * 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.config;
+
+/**
+ * Settings for <code>LoginCommand</code> class.
+ *
+ *
+ */
+public class LoginCommandSettings
+{
+    public static final String SERVER_MATCH_OVERRIDE = "all";
+
+    private String className;
+    private String server;
+    private boolean perClientAuthentication;
+
+    /**
+     * Create a new <code>LoginCommandSettings</code> instance with default settings.
+     */
+    public LoginCommandSettings()
+    {
+        perClientAuthentication = false;
+    }
+
+    /**
+     * Returns the class name associated with the settings.
+     *
+     * @return The class name.
+     */
+    public String getClassName()
+    {
+        return className;
+    }
+
+    /**
+     * Sets the class name associated with the settings.
+     *
+     * @param className The class name.
+     */
+    public void setClassName(String className)
+    {
+        this.className = className;
+    }
+
+    /**
+     * Returns the server name associated with the settings.
+     *
+     * @return The server name.
+     */
+    public String getServer()
+    {
+        return server;
+    }
+
+    /**
+     * Sets the server name associated with the settings.
+     *
+     * @param server The server name.
+     */
+    public void setServer(String server)
+    {
+        this.server = server;
+    }
+
+    /**
+     * Returns whether per client authentication is enabled or not.
+     *
+     * @return <code>true</code> if per client authentication is enabled;
+     * otherwise <code>false</code>.
+     */
+    public boolean isPerClientAuthentication()
+    {
+        return perClientAuthentication;
+    }
+
+    /**
+     * Sets whether per client authentication is enabled or not.
+     *
+     * @param perClientAuthentication <code>true</code> if per client authentication
+     * is enabled; otherwise <code>false</code>.
+     */
+    public void setPerClientAuthentication(boolean perClientAuthentication)
+    {
+        this.perClientAuthentication = perClientAuthentication;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/PropertiesSettings.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/PropertiesSettings.java b/common/src/main/java/flex/messaging/config/PropertiesSettings.java
new file mode 100644
index 0000000..4fa0a83
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/PropertiesSettings.java
@@ -0,0 +1,99 @@
+/*
+ * 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.config;
+
+import java.util.List;
+
+/**
+ * Holds any child element of the properties section of the services configuration.
+ * <p>
+ * If a property is a simple element with a text value then it is stored as a String
+ * using the element name as the property name. If the same element appears again then
+ * the element is converted to a List of values and further occurences are simply added
+ * to the List.
+ * </p>
+ * <p>
+ * If a property element has child elements the children are recursively processed
+ * and added as a Map.
+ * </p>
+ *
+ *
+ */
+public abstract class PropertiesSettings
+{
+    protected final ConfigMap properties;
+
+    public PropertiesSettings()
+    {
+        properties = new ConfigMap();
+    }
+
+    public final void addProperties(ConfigMap p)
+    {
+        properties.addProperties(p);
+    }
+
+    public ConfigMap getProperties()
+    {
+        return properties;
+    }
+
+    public final String getProperty(String name)
+    {
+        return getPropertyAsString(name, null);
+    }
+
+    public final void addProperty(String name, String value)
+    {
+        properties.addProperty(name, value);
+    }
+
+    public final void addProperty(String name, ConfigMap value)
+    {
+        properties.addProperty(name, value);
+    }
+
+    public final ConfigMap getPropertyAsMap(String name, ConfigMap defaultValue)
+    {
+        return properties.getPropertyAsMap(name, defaultValue);
+    }
+
+    public final String getPropertyAsString(String name, String defaultValue)
+    {
+        return properties.getPropertyAsString(name, defaultValue);
+    }
+
+    public final List getPropertyAsList(String name, List defaultValue)
+    {
+        return properties.getPropertyAsList(name, defaultValue);
+    }
+
+    public final int getPropertyAsInt(String name, int defaultValue)
+    {
+        return properties.getPropertyAsInt(name, defaultValue);
+    }
+
+    public final boolean getPropertyAsBoolean(String name, boolean defaultValue)
+    {
+        return properties.getPropertyAsBoolean(name, defaultValue);
+    }
+
+    public final long getPropertyAsLong(String name, long defaultValue)
+    {
+        return properties.getPropertyAsLong(name, defaultValue);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/SecurityConstraint.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/SecurityConstraint.java b/common/src/main/java/flex/messaging/config/SecurityConstraint.java
new file mode 100644
index 0000000..0b7638b
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/SecurityConstraint.java
@@ -0,0 +1,123 @@
+/*
+ * 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.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Security constraints are used by the login manager to secure access to
+ * destinations and endpoints.
+ */
+public class SecurityConstraint
+{
+    /**
+     * String constant for basic authentication.
+     */
+    public static final String BASIC_AUTH_METHOD = "Basic";
+
+    /**
+     * String constant for custom authentication.
+     */
+    public static final String CUSTOM_AUTH_METHOD = "Custom";
+
+    private final String id;
+    private String method;
+    private List roles;
+
+    /**
+     * Creates an anonymous <code>SecurityConstraint</code> instance.
+     */
+    public SecurityConstraint()
+    {
+        this(null);
+    }
+
+    /**
+     * Creates a <code>SecurityConstraint</code> instance with an id.
+     *
+     * @param id The id of the <code>SecurityConstraint</code> instance.
+     */
+    public SecurityConstraint(String id)
+    {
+        this.id = id;
+        method = CUSTOM_AUTH_METHOD;
+    }
+
+    /**
+     * Returns a list of roles of the <code>SecurityConstraint</code>.
+     *
+     * @return List of roles.
+     */
+    public List getRoles()
+    {
+        return roles;
+    }
+
+    /**
+     * Adds a role to the list of roles of the <code>SecurityConstraint</code>.
+     *
+     * @param role New role to add to the list of roles.
+     */
+    public void addRole(String role)
+    {
+        if (role == null)
+            return;
+
+        if (roles == null)
+            roles = new ArrayList();
+
+            roles.add(role);
+    }
+
+    /**
+     * Returns the id of the <code>SecurityConstraint</code>.
+     *
+     * @return The id of the <code>SecurityConstraint</code>.
+     */
+    public String getId()
+    {
+        return id;
+    }
+
+    /**
+     * Returns the authorization method of the <code>SecurityConstraint</code>.
+     *
+     * @return Authorization method.
+     */
+    public String getMethod()
+    {
+        return method;
+    }
+
+    /**
+     * Sets the authorization method of the <code>SecurityConstraint</code>.
+     * Valid values are Basic and Custom.
+     *
+     * @param method The authentication method to set which can be custom or basic.
+     */
+    public void setMethod(String method)
+    {
+        if (method == null)
+            return;
+
+        if (CUSTOM_AUTH_METHOD.equalsIgnoreCase(method))
+            this.method = CUSTOM_AUTH_METHOD;
+        else if (BASIC_AUTH_METHOD.equalsIgnoreCase(method))
+            this.method = BASIC_AUTH_METHOD;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/ServiceSettings.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/ServiceSettings.java b/common/src/main/java/flex/messaging/config/ServiceSettings.java
new file mode 100644
index 0000000..44d95b5
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/ServiceSettings.java
@@ -0,0 +1,165 @@
+/*
+ * 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.config;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A service represents a high-level grouping of
+ * functionality to which the message broker can
+ * delegate messages. Services specify which
+ * message types they're interested in and use
+ * adapters to carry out a message's for a
+ * destination.
+ * <p>
+ * A service maintains a list of destinations which
+ * effectively represents a &quot;whitelist&quot;
+ * of actions allowed by that service.
+ * </p>
+ *
+ *
+ */
+public class ServiceSettings extends PropertiesSettings
+{
+    private final String id;
+    private String sourceFile;
+    private String className;
+
+    private AdapterSettings defaultAdapterSettings;
+    private final Map adapterSettings;
+    private final List defaultChannels;
+    private final Map destinationSettings;
+    private SecurityConstraint securityConstraint;
+
+    public ServiceSettings(String id)
+    {
+        this.id = id;
+        destinationSettings = new HashMap();
+        adapterSettings = new HashMap(2);
+        defaultChannels = new ArrayList(4);
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    String getSourceFile()
+    {
+        return sourceFile;
+    }
+
+    void setSourceFile(String sourceFile)
+    {
+        this.sourceFile = sourceFile;
+    }
+
+    public String getClassName()
+    {
+        return className;
+    }
+
+    public void setClassName(String name)
+    {
+        className = name;
+    }
+
+    /*
+     *  SERVER ADAPTERS
+     */
+    public AdapterSettings getDefaultAdapter()
+    {
+        return defaultAdapterSettings;
+    }
+
+    public AdapterSettings getAdapterSettings(String id)
+    {
+        return (AdapterSettings)adapterSettings.get(id);
+    }
+
+    public Map getAllAdapterSettings()
+    {
+        return adapterSettings;
+    }
+
+    public void addAdapterSettings(AdapterSettings a)
+    {
+        adapterSettings.put(a.getId(), a);
+        if (a.isDefault())
+        {
+            defaultAdapterSettings = a;
+        }
+    }
+
+    /*
+     *  DEFAULT CHANNELS
+     */
+    public void addDefaultChannel(ChannelSettings c)
+    {
+        defaultChannels.add(c);
+    }
+
+    public List getDefaultChannels()
+    {
+        return defaultChannels;
+    }
+
+    /*
+     *  DEFAULT SECURITY
+     */
+
+    /**
+     * Gets the <code>SecurityConstraint</code> that will be applied to all
+     * destinations of the service, or <code>null</code> if no constraint has
+     * been registered.
+     *
+     * @return the <code>SecurityConstraint</code> for this service.
+     */
+    public SecurityConstraint getConstraint()
+    {
+        return securityConstraint;
+    }
+
+    /**
+     * Sets the security constraint to be applied to all destinations of the service.
+     * Security constraints restrict which clients can contact this destination. Use
+     * <code>null</code> to remove an existing constraint.
+     *
+     * @param sc the <code>SecurityConstraint</code> to apply to this
+     * service.
+     */
+    public void setConstraint(SecurityConstraint sc)
+    {
+        securityConstraint = sc;
+    }
+
+    /*
+     *  DESTINATIONS
+     */
+    public Map getDestinationSettings()
+    {
+        return destinationSettings;
+    }
+
+    public void addDestinationSettings(DestinationSettings dest)
+    {
+        destinationSettings.put(dest.getId(), dest);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/ServicesConfiguration.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/ServicesConfiguration.java b/common/src/main/java/flex/messaging/config/ServicesConfiguration.java
new file mode 100644
index 0000000..561d75b
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/ServicesConfiguration.java
@@ -0,0 +1,70 @@
+/*
+ * 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.config;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base interface for Flex Data Services configuration.
+ *
+ * Implementations may have different levels of detail
+ * based on how much of the configuration is supported.
+ *
+ *
+ */
+public interface ServicesConfiguration
+{
+    /*
+     * CHANNEL CONFIGURATION
+     */
+
+    void addChannelSettings(String id, ChannelSettings settings);
+
+    ChannelSettings getChannelSettings(String ref);
+
+    Map getAllChannelSettings();
+
+    /*
+     * DEFAULT CHANNELS CONFIGURATION
+     */
+    void addDefaultChannel(String id);
+
+    List getDefaultChannels();
+
+    /*
+     * SERVICE CONFIGURATION
+     */
+
+    void addServiceSettings(ServiceSettings settings);
+
+    ServiceSettings getServiceSettings(String id);
+
+    List getAllServiceSettings();
+
+    /*
+     * LOGGING CONFIGURATION
+     */
+    void setLoggingSettings(LoggingSettings settings);
+
+    LoggingSettings getLoggingSettings();
+
+    /* CLUSTER CONFIGURATION */
+    ClusterSettings getClusterSettings(String clusterId);
+
+    ClusterSettings getDefaultCluster();
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/ServicesDependencies.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/ServicesDependencies.java b/common/src/main/java/flex/messaging/config/ServicesDependencies.java
new file mode 100644
index 0000000..92b7c34
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/ServicesDependencies.java
@@ -0,0 +1,747 @@
+/*
+ * 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.config;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import flex.messaging.LocalizedException;
+
+/**
+ * Flex MXMLC compiler uses the result of the client configuration parser
+ * to generate mixin initialization source code to be added to the SWF by
+ * PreLink. It also requires a list of channel classes to be added as
+ * dependencies.
+ *
+ *
+ */
+public class ServicesDependencies
+{
+    private static final String ADVANCED_CHANNELSET_CLASS = "mx.messaging.AdvancedChannelSet";
+    private static final String ADVANCED_MESSAGING_SUPPORT_CLASS = "flex.messaging.services.AdvancedMessagingSupport";
+    private static final String REDIRECT_URL = "redirect-url";
+    
+    private boolean containsClientLoadBalancing;
+    private String xmlInit = "";
+    private StringBuffer imports = new StringBuffer();
+    private StringBuffer references = new StringBuffer();
+    private List channelClasses;
+    private Map configPaths;
+    private Map lazyAssociations;
+    
+    private static final List channel_excludes = new ArrayList();
+    static
+    {
+        channel_excludes.add(REDIRECT_URL);
+    }
+
+    public static final boolean traceConfig = (System.getProperty("trace.config") != null);
+
+    public ServicesDependencies(String path, String parserClass, String contextRoot)
+    {
+        ClientConfiguration config = getClientConfiguration(path, parserClass);
+
+        if (config != null)
+        {
+            Map importMap = new HashMap();
+            lazyAssociations = new HashMap();
+            configPaths = config.getConfigPaths();
+            xmlInit = codegenXmlInit(config, contextRoot, importMap);
+            codegenServiceImportsAndReferences(importMap, imports, references);
+            channelClasses = listChannelClasses(config);
+        }
+    }
+
+    public Set getLazyAssociations(String destination)
+    {
+        if (lazyAssociations == null)
+        {
+            lazyAssociations = new HashMap();
+        }
+
+        return (Set)lazyAssociations.get(destination);
+    }
+
+    public void addLazyAssociation(String destination, String associationProp)
+    {
+        Set la = getLazyAssociations(destination);
+        if (la == null)
+        {
+            la = new HashSet();
+            lazyAssociations.put(destination, la);
+        }
+        la.add(associationProp);
+    }
+
+    public String getServerConfigXmlInit()
+    {
+        return xmlInit;
+    }
+
+    public String getImports()
+    {
+        return imports.toString();
+    }
+
+    public String getReferences()
+    {
+        return references.toString();
+    }
+
+    public List getChannelClasses()
+    {
+        return channelClasses;
+    }
+
+    public void addChannelClass(String className)
+    {
+        channelClasses.add(className);
+    }
+
+    public void addConfigPath(String path, long modified)
+    {
+        configPaths.put(path, new Long(modified));
+    }
+
+    public Map getConfigPaths()
+    {
+        return configPaths;
+    }
+    
+    /**
+     * Gets ActionScript source file for a class. The class will be compiled as 
+     * a mixin and initialize Flex at runtime.
+     * 
+     * @param packageName - the package compiled into the generated source.
+     * @param className - the class name of the generated source.
+     * @return A String that represents an ActionScript Source file.
+     */
+        public String getServicesInitSource(String packageName, String className)
+    {
+        StringBuilder sb = new StringBuilder(2048);
+
+        sb.append("package ").append(packageName).append("\n");
+        sb.append("{\n\n");
+        sb.append("import mx.core.IFlexModuleFactory;\n");
+        sb.append("import flash.net.registerClassAlias;\n");
+        sb.append("import flash.net.getClassByAlias;\n");
+
+        // generated imports
+        sb.append(getImports());
+
+        sb.append("\n[Mixin]\n");
+        sb.append("public class ").append(className).append("\n");
+        sb.append("{\n");
+        sb.append("    public function ").append(className).append("()\n");
+        sb.append("    {\n");
+        sb.append("        super();\n");
+        sb.append("    }\n\n");
+        sb.append("    public static function init(fbs:IFlexModuleFactory):void\n");
+        sb.append("    {\n");
+
+        // code for init
+        sb.append(getServerConfigXmlInit());
+        sb.append("    }\n\n");
+
+        // generated variables to create references
+        sb.append(getReferences());
+        sb.append("}\n");
+        sb.append("}\n");
+
+        return sb.toString();
+    }
+
+    public static ClientConfiguration getClientConfiguration(String path, String parserClass)
+    {
+        ClientConfiguration config = new ClientConfiguration();
+
+        ConfigurationParser parser = getConfigurationParser(parserClass);
+
+        if (parser == null)
+        {
+            // "Unable to create a parser to load messaging configuration."
+            LocalizedException lme = new LocalizedException();
+            lme.setMessage(10138);
+            throw lme;
+        }
+
+        LocalFileResolver local = new LocalFileResolver();
+        parser.parse(path, local, config);
+
+        config.addConfigPath(path, new File(path).lastModified());
+
+        return config;
+    }
+
+    static ConfigurationParser getConfigurationParser(String className)
+    {
+        ConfigurationParser parser = null;
+        Class parserClass = null;
+
+        // Check for Custom Parser Specification
+        if (className != null)
+        {
+            try
+            {
+                parserClass = Class.forName(className);
+                parser = (ConfigurationParser)parserClass.newInstance();
+            }
+            catch (Throwable t)
+            {
+                if (traceConfig)
+                {
+                    System.out.println("Could not load services configuration parser as: " + className);
+                }
+            }
+        }
+
+        // Try Sun JRE 1.4 / Apache Xalan Based Implementation
+        if (parser == null)
+        {
+            try
+            {
+                Class.forName("org.apache.xpath.CachedXPathAPI");
+                className = "flex.messaging.config.ApacheXPathClientConfigurationParser";
+                parserClass = Class.forName(className);
+                parser = (ConfigurationParser)parserClass.newInstance();
+            }
+            catch (Throwable t)
+            {
+                if (traceConfig)
+                {
+                    System.out.println("Could not load configuration parser as: " + className);
+                }
+            }
+        }
+
+        // Try Sun JRE 1.5 Based Implementation
+        if (parser == null)
+        {
+            try
+            {
+                className = "flex.messaging.config.XPathClientConfigurationParser";
+                parserClass = Class.forName(className);
+                // double-check, on some systems the above loads but the import classes don't
+                Class.forName("javax.xml.xpath.XPathExpressionException");
+
+                parser = (ConfigurationParser)parserClass.newInstance();
+            }
+            catch (Throwable t)
+            {
+                if (traceConfig)
+                {
+                    System.out.println("Could not load configuration parser as: " + className);
+                }
+            }
+        }
+
+        if (traceConfig && parser != null)
+        {
+            System.out.println("Services Configuration Parser: " + parser.getClass().getName());
+        }
+
+        return parser;
+    }
+
+    private static List listChannelClasses(ServicesConfiguration config)
+    {
+        List channelList = new ArrayList();
+        Iterator it = config.getAllChannelSettings().values().iterator();
+        while (it.hasNext())
+        {
+            ChannelSettings settings = (ChannelSettings)it.next();
+            if (!settings.serverOnly)
+            {
+                String clientType = settings.getClientType();
+                channelList.add(clientType);
+            }
+        }
+
+        return channelList;
+    }
+
+    /**
+     * Emits source code declaration of public var xml:XML (unnamed package), containing ServicesConfiguration as e4x.
+     */
+    private String codegenXmlInit(ServicesConfiguration config, String contextRoot, Map serviceImportMap)
+    {
+        StringBuffer e4x = new StringBuffer();
+        String channelSetImplToImport = null;
+
+        e4x.append("<services>\n");
+
+        // Add default channels of the application
+        if (config.getDefaultChannels().size() > 0)
+        {
+            e4x.append("\t<default-channels>\n");
+            for (Iterator chanIter = config.getDefaultChannels().iterator(); chanIter.hasNext();)
+            {
+                String id = (String)chanIter.next();
+                e4x.append("\t\t<channel ref=\"" + id + "\"/>\n");
+            }
+            e4x.append("\t</default-channels>\n");
+        }
+
+        ClusterSettings defaultCluster = config.getDefaultCluster();
+        // Do not add the cluster tag if the default cluster does not have
+        // client side load balancing.
+        if (defaultCluster != null && !defaultCluster.getURLLoadBalancing())
+            defaultCluster = null;
+
+        for (Iterator servIter = config.getAllServiceSettings().iterator(); servIter.hasNext();)
+        {
+            ServiceSettings entry = (ServiceSettings)servIter.next();
+
+            // FIXME: Need to find another way to skip BootstrapServices
+            // Skip services with no message types
+            /*
+            String messageTypes = entry.getMessageTypesString();
+            if (messageTypes == null)
+                continue;
+            */
+
+            String serviceType = entry.getId();
+            e4x.append("\t<service id=\"");
+            e4x.append(serviceType);
+            e4x.append("\"");
+            e4x.append(">\n");
+
+            String serviceClass = entry.getClassName();
+            if (ADVANCED_MESSAGING_SUPPORT_CLASS.equals(serviceClass))
+                channelSetImplToImport = ADVANCED_CHANNELSET_CLASS;
+
+            String useTransactionsStr = entry.getProperties().getPropertyAsString("use-transactions", null);
+            if (useTransactionsStr != null)
+            {
+                e4x.append("\t\t<properties>\n\t\t\t<use-transactions>" + useTransactionsStr + "</use-transactions>\n");
+                e4x.append("\t\t</properties>\n");
+            }
+
+            for (Iterator destIter = entry.getDestinationSettings().values().iterator(); destIter.hasNext();)
+            {
+                DestinationSettings dest = (DestinationSettings) destIter.next();
+                String destination = dest.getId();
+                e4x.append("\t\t<destination id=\"" + destination + "\">\n");
+
+                // add in the identity properties
+                ConfigMap metadata = dest.getProperties().getPropertyAsMap("metadata", null);
+                boolean closePropTag = false;
+                if (metadata != null)
+                {
+                    e4x.append("\t\t\t<properties>\n\t\t\t\t<metadata\n");
+                    String extendsStr = metadata.getPropertyAsString("extends", null);
+                    if (extendsStr != null)
+                    {
+                        e4x.append(" extends=\"");
+                        e4x.append(extendsStr);
+                        e4x.append("\"");
+                    }
+                    e4x.append(">");
+                    closePropTag = true;
+                    List identities = metadata.getPropertyAsList("identity", null);
+                    if (identities != null)
+                    {
+                        Iterator it = identities.iterator();
+                        while (it.hasNext())
+                        {
+                            Object o = it.next();
+                            String identityName = null;
+                            String undefinedValue = null;
+                            if (o instanceof String)
+                            {
+                                identityName = (String) o;
+                            }
+                            else if (o instanceof ConfigMap)
+                            {
+                                identityName = ((ConfigMap) o).getPropertyAsString("property", null);
+                                undefinedValue = ((ConfigMap) o).getPropertyAsString("undefined-value", null);
+                            }
+
+                            if (identityName != null)
+                            {
+                                e4x.append("\t\t\t\t\t<identity property=\"");
+                                e4x.append(identityName);
+                                e4x.append("\"");
+                                if (undefinedValue != null)
+                                {
+                                    e4x.append(" undefined-value=\"");
+                                    e4x.append(undefinedValue);
+                                    e4x.append("\"");
+                                }
+                                e4x.append("/>\n");
+                            }
+                        }
+                    }
+                    // add associations which reference other data service destinations
+                    codegenServiceAssociations(metadata, e4x, destination, "one-to-many");
+                    codegenServiceAssociations(metadata, e4x, destination, "many-to-many");
+                    codegenServiceAssociations(metadata, e4x, destination, "one-to-one");
+                    codegenServiceAssociations(metadata, e4x, destination, "many-to-one");
+
+                    e4x.append("\t\t\t\t</metadata>\n");
+                }
+
+                String itemClass = dest.getProperties().getPropertyAsString("item-class", null);
+                if (itemClass != null)
+                {
+                    if (!closePropTag)
+                    {
+                        e4x.append("\t\t\t<properties>\n");
+                        closePropTag = true;
+                    }
+
+                    e4x.append("\t\t\t\t<item-class>");
+                    e4x.append(itemClass);
+                    e4x.append("</item-class>\n");
+                }
+
+                // add in sub-set of network-related destination properties
+                ConfigMap network = dest.getProperties().getPropertyAsMap("network", null);
+                ConfigMap clusterInfo = null;
+                ConfigMap pagingInfo = null;
+                ConfigMap reconnectInfo = null;
+                if (network != null || defaultCluster != null)
+                {
+                    if (!closePropTag)
+                    {
+                        e4x.append("\t\t\t<properties>\n");
+                        closePropTag = true;
+                    }
+                    e4x.append("\t\t\t\t<network>\n");
+
+                    if (network != null)
+                        pagingInfo = network.getPropertyAsMap("paging", null);
+                    if (pagingInfo != null)
+                    {
+                        String enabled = pagingInfo.getPropertyAsString("enabled", "false");
+                        e4x.append("\t\t\t\t\t<paging enabled=\"");
+                        e4x.append(enabled);
+                        e4x.append("\"");
+                        // Always put page size even if it is disabled as we can
+                        // end up using this for nested properties with lazy="true".
+                        // supporting pageSize for backwards compatibility but config options are not camelCase in general.
+                        String size = pagingInfo.getPropertyAsString("page-size", pagingInfo.getPropertyAsString("pageSize", null));
+                        if (size != null)
+                        {
+                            e4x.append(" page-size=\"");
+                            e4x.append(size);
+                            e4x.append("\"");
+
+                            // Included so that newer compilers can work with older clients
+                            e4x.append(" pageSize=\"");
+                            e4x.append(size);
+                            e4x.append("\"");
+                        }
+                        e4x.append("/>\n");
+                    }
+
+                    if (network != null)
+                        reconnectInfo = network.getPropertyAsMap("reconnect", null);
+                    if (reconnectInfo != null)
+                    {
+                        String fetchOption = reconnectInfo.getPropertyAsString("fetch", "IDENTITY");
+                        e4x.append("\t\t\t\t\t<reconnect fetch=\"");
+                        e4x.append(fetchOption.toUpperCase());
+                        e4x.append("\" />\n");
+                    }
+
+                    if (network != null)
+                    {
+                        String reliable = network.getPropertyAsString("reliable", "false");
+                        if (Boolean.valueOf(reliable).booleanValue()) // No need the default value for the setting.
+                        {
+                            e4x.append("\t\t\t\t\t<reliable>");
+                            e4x.append(reliable);
+                            e4x.append("</reliable>\n");
+                        }
+                    }
+
+                    if (network != null)
+                        clusterInfo = network.getPropertyAsMap("cluster", null);
+                    if (clusterInfo != null)
+                    {
+                        String clusterId = clusterInfo.getPropertyAsString("ref", null);
+
+                        ClusterSettings clusterSettings = config.getClusterSettings(clusterId);
+                        if (clusterSettings != null &&
+                            clusterSettings.getURLLoadBalancing())
+                        {
+                            e4x.append("\t\t\t\t\t<cluster ref=\"");
+                            e4x.append(clusterId);
+                            e4x.append("\"/>\n");
+                        }
+                    }
+                    else if (defaultCluster != null)
+                    {
+                        e4x.append("\t\t\t\t\t<cluster");
+                        if (defaultCluster.getClusterName() != null)
+                        {
+                            e4x.append(" ref=\"");
+                            e4x.append(defaultCluster.getClusterName());
+                            e4x.append("\"");
+                        }
+                        e4x.append("/>\n");
+                    }
+                    e4x.append("\t\t\t\t</network>\n");
+                }
+
+                String useTransactions = dest.getProperties().getPropertyAsString("use-transactions", null);
+
+                if (useTransactions !=null)
+                {
+                    if (!closePropTag)
+                    {
+                        e4x.append("\t\t\t<properties>\n");
+                        closePropTag = true;
+                    }
+                    e4x.append("\t\t\t\t<use-transactions>" + useTransactions + "</use-transactions>\n");
+                }
+
+                String autoSyncEnabled = dest.getProperties().getPropertyAsString("auto-sync-enabled", "true");
+
+                if (autoSyncEnabled.equalsIgnoreCase("false"))
+                {
+                    if (!closePropTag)
+                    {
+                        e4x.append("\t\t\t<properties>\n");
+                        closePropTag = true;
+                    }
+                    e4x.append("\t\t\t\t<auto-sync-enabled>false</auto-sync-enabled>\n");
+                }
+
+                if (closePropTag)
+                {
+                    e4x.append("\t\t\t</properties>\n");
+                }
+
+                e4x.append("\t\t\t<channels>\n");
+                for (Iterator chanIter = dest.getChannelSettings().iterator(); chanIter.hasNext();)
+                {
+                    e4x.append("\t\t\t\t<channel ref=\"" + ((ChannelSettings) chanIter.next()).getId() + "\"/>\n");
+                }
+                e4x.append("\t\t\t</channels>\n");
+                e4x.append("\t\t</destination>\n");
+            }
+            e4x.append("\t</service>\n");
+        }
+        // channels
+        e4x.append("\t<channels>\n");
+        String channelType;
+        for (Iterator chanIter = config.getAllChannelSettings().values().iterator(); chanIter.hasNext();)
+        {
+            ChannelSettings chan = (ChannelSettings) chanIter.next();
+            if (chan.getServerOnly()) // Skip server-only channels.
+                continue;
+            channelType = chan.getClientType();
+            serviceImportMap.put(channelType, channelType);
+            e4x.append("\t\t<channel id=\"" + chan.getId() + "\" type=\"" + channelType + "\">\n");
+            StringBuffer channelProps = new StringBuffer();
+            containsClientLoadBalancing = false;
+            channelProperties(chan.getProperties(), channelProps, "\t\t\t\t");
+            if (!containsClientLoadBalancing) // Add the uri, only when there is no client-load-balancing defined.
+                e4x.append("\t\t\t<endpoint uri=\"" + chan.getClientParsedUri(contextRoot) + "\"/>\n");
+            containsClientLoadBalancing = false;
+            e4x.append("\t\t\t<properties>\n");
+            e4x.append(channelProps);
+            e4x.append("\t\t\t</properties>\n");
+            e4x.append("\t\t</channel>\n");
+        }
+        e4x.append("\t</channels>\n");
+        FlexClientSettings flexClientSettings = (config instanceof ClientConfiguration) ? ((ClientConfiguration)config).getFlexClientSettings() : null;
+        if (flexClientSettings != null && flexClientSettings.getHeartbeatIntervalMillis() > 0)
+        {
+            e4x.append("\t<flex-client>\n");
+            e4x.append("\t\t<heartbeat-interval-millis>");
+            e4x.append(flexClientSettings.getHeartbeatIntervalMillis());
+            e4x.append("</heartbeat-interval-millis>");
+            e4x.append("\t</flex-client>\n");
+        }
+        e4x.append("</services>");
+
+        StringBuffer advancedMessagingSupport = new StringBuffer();
+        if (channelSetImplToImport != null)
+        {
+            serviceImportMap.put("ChannelSetImpl", channelSetImplToImport);
+
+            // Codegen same class alias registration as is done by flex2.tools.Prelink#codegenRemoteClassAliases(Map<String,String>).
+            // This codegen isn't processed by PreLink.
+            String alias = "flex.messaging.messages.ReliabilityMessage";
+            String className = "mx.messaging.messages.ReliabilityMessage";
+            advancedMessagingSupport.append("     ServerConfig.channelSetFactory = AdvancedChannelSet;\n");
+            advancedMessagingSupport.append("     try {\n");
+            advancedMessagingSupport.append("     if (flash.net.getClassByAlias(\"" + alias + "\") == null){\n");
+            advancedMessagingSupport.append("         flash.net.registerClassAlias(\"" + alias + "\", " + className + ");}\n");
+            advancedMessagingSupport.append("     } catch (e:Error) {\n");
+            advancedMessagingSupport.append("         flash.net.registerClassAlias(\"" + alias + "\", " + className + "); }\n");
+            if (flexClientSettings != null && flexClientSettings.getReliableReconnectDurationMillis() > 0)
+            {
+                advancedMessagingSupport.append("     AdvancedChannelSet.reliableReconnectDuration =");
+                advancedMessagingSupport.append(flexClientSettings.getReliableReconnectDurationMillis());
+                advancedMessagingSupport.append(";\n");
+            }
+        }
+        String generatedChunk = "\n     ServerConfig.xml =\n" + e4x.toString() + ";\n" + advancedMessagingSupport.toString();
+
+        return generatedChunk;
+    }
+
+    /**
+     * Process channel properties recursively.
+     */
+    private void channelProperties(ConfigMap properties, StringBuffer buf, String indent)
+    {
+        for (Iterator nameIter = properties.propertyNames().iterator(); nameIter.hasNext();)
+        {
+            String name = (String)nameIter.next();
+            Object value = properties.get(name);
+            if (value instanceof String)
+            {
+                addStringProperty(buf, indent, name, (String)value);
+            }
+            else if (value instanceof List)
+            {
+                List children = (List)value;
+                for (Iterator childrenIter = children.iterator(); childrenIter.hasNext();)
+                    addStringProperty(buf, indent, name, (String)childrenIter.next());
+            }
+            else if (value instanceof ConfigMap)
+            {
+                ConfigMap childProperties = (ConfigMap)value;
+                buf.append(indent);
+                buf.append("<" + name + ">\n");
+                if (ConfigurationConstants.CLIENT_LOAD_BALANCING_ELEMENT.equals(name))
+                    containsClientLoadBalancing = true;
+                channelProperties(childProperties, buf, indent + "\t");
+                buf.append(indent);
+                buf.append("</" + name + ">\n");
+            }
+        }
+    }
+
+    private void addStringProperty(StringBuffer buf, String indent, String name, String value)
+    {
+        if (!channel_excludes.contains(name))
+        {
+            buf.append(indent);
+            buf.append("<" + name + ">" + value + "</" + name + ">\n");
+        }
+    }
+
+    /**
+     * Analyze code gen service associations.
+     * @param metadata the ConfigMap object
+     * @param e4x the buffer object
+     * @param destination the current destination
+     * @param relation the relationship 
+     */
+    public void codegenServiceAssociations(ConfigMap metadata, StringBuffer e4x, String destination, String relation)
+    {
+        List references = metadata.getPropertyAsList(relation, null);
+        if (references != null)
+        {
+            Iterator it = references.iterator();
+            while (it.hasNext())
+            {
+                Object ref = it.next();
+                if (ref instanceof ConfigMap)
+                {
+                    ConfigMap refMap = (ConfigMap) ref;
+                    String name = refMap.getPropertyAsString("property", null);
+                    String associatedDestination = refMap.getPropertyAsString("destination", null);
+                    String lazy = refMap.getPropertyAsString("lazy", null);
+                    String loadOnDemand = refMap.getPropertyAsString("load-on-demand", null);
+                    String hierarchicalEvents = refMap.getPropertyAsString("hierarchical-events", null);
+                    String pageSize = refMap.getPropertyAsString("page-size", refMap.getPropertyAsString("pageSize", null));
+                    String pagedUpdates = refMap.getPropertyAsString("paged-updates", null);
+                    String cascade = refMap.getPropertyAsString("cascade", null);
+                    String ordered = refMap.getPropertyAsString("ordered", null);
+                    e4x.append("\t\t\t\t\t<");
+                    e4x.append(relation);
+                    if (lazy != null)
+                    {
+                        e4x.append(" lazy=\"");
+                        e4x.append(lazy);
+                        e4x.append("\"");
+
+                        if (Boolean.valueOf(lazy.toLowerCase().trim()).booleanValue())
+                        {
+                            addLazyAssociation(destination, name);
+                        }
+                    }
+                    e4x.append(" property=\"");
+                    e4x.append(name);
+                    e4x.append("\" destination=\"");
+                    e4x.append(associatedDestination);
+                    e4x.append("\"");
+                    String readOnly = refMap.getPropertyAsString("read-only", null);
+                    if (readOnly != null && readOnly.equalsIgnoreCase("true"))
+                    {
+                        e4x.append(" read-only=\"true\"");
+                    }
+                    if (loadOnDemand != null && loadOnDemand.equalsIgnoreCase("true"))
+                        e4x.append(" load-on-demand=\"true\"");
+                    if (hierarchicalEvents != null && hierarchicalEvents.equalsIgnoreCase("true"))
+                        e4x.append(" hierarchical-events=\"true\"");
+                    if (pagedUpdates != null)
+                        e4x.append(" paged-updates=\"" + pagedUpdates + "\"");
+                    if (pageSize != null)
+                        e4x.append(" page-size=\"" + pageSize + "\"");
+                    if (cascade != null)
+                        e4x.append(" cascade=\"" + cascade + "\"");
+                    if (ordered != null)
+                        e4x.append(" ordered=\"" + ordered + "\"");
+                    e4x.append("/>\n");
+                }
+            }
+        }
+    }
+
+    /**
+     * This method will return an import and variable reference for channels specified in the map.
+     * @param map HashMap containing the client side channel type to be used, typically of the form
+     * "mx.messaging.channels.XXXXChannel", where the key and value are equal.
+     * @param imports StringBuffer of the imports needed for the given channel definitions
+     * @param references StringBuffer of the required references so that these classes will be linked in.
+     */
+    public static void codegenServiceImportsAndReferences(Map map, StringBuffer imports, StringBuffer references)
+    {
+        String channelSetImplType = (String)map.remove("ChannelSetImpl");
+        String type;
+        imports.append("import mx.messaging.config.ServerConfig;\n");
+        references.append("   // static references for configured channels\n");
+        for (Iterator chanIter = map.values().iterator(); chanIter.hasNext();)
+        {
+            type = (String)chanIter.next();
+            imports.append("import ");
+            imports.append(type);
+            imports.append(";\n");
+            references.append("   private static var ");
+            references.append(type.replace('.', '_'));
+            references.append("_ref:");
+            references.append(type.substring(type.lastIndexOf(".") +1) +";\n");
+        }
+        if (channelSetImplType != null)
+            imports.append("import mx.messaging.AdvancedChannelSet;\nimport mx.messaging.messages.ReliabilityMessage;\n");
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/TargetSettings.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/TargetSettings.java b/common/src/main/java/flex/messaging/config/TargetSettings.java
new file mode 100644
index 0000000..3bbbf4d
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/TargetSettings.java
@@ -0,0 +1,78 @@
+/*
+ * 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.config;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import flex.messaging.log.LogCategories;
+
+/**
+ * A logging target must specify the class name
+ * of the implementation, the level of logging events
+ * it will accept, a list of filters for logging
+ * categories it is interested in, and a collection of
+ * properties required to initialize the target.
+ *
+ *
+ */
+public class TargetSettings extends PropertiesSettings
+{
+    private String className;
+    private String level;
+    private List filters;
+
+    public TargetSettings(String className)
+    {
+        this.className = className;
+    }
+
+    public String getClassName()
+    {
+        return className;
+    }
+
+    public String getLevel()
+    {
+        return level;
+    }
+
+    public void setLevel(String level)
+    {
+        this.level = level;
+    }
+
+    public List getFilters()
+    {
+        return filters;
+    }
+
+    public void addFilter(String filter)
+    {
+        if (filters == null)
+            filters = new ArrayList();
+
+        // Replace DataService with Service.Data for backwards compatibility,
+        // excluding DataService.coldfusion.
+        if (filter.startsWith("DataService") && !filter.equals("DataService.coldfusion"))
+            filter = filter.replaceFirst("DataService", LogCategories.SERVICE_DATA);
+
+        filters.add(filter);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/TokenReplacer.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/TokenReplacer.java b/common/src/main/java/flex/messaging/config/TokenReplacer.java
new file mode 100644
index 0000000..90c4fd0
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/TokenReplacer.java
@@ -0,0 +1,202 @@
+/*
+ * 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.config;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import flex.messaging.log.Log;
+import flex.messaging.log.LogCategories;
+import flex.messaging.util.StringUtils;
+
+/**
+ * This class is used by configuration parser to replace tokens of the format
+ * {...} with actual values. The value can either come from a JVM property 
+ * (eg. -Dmy.channel.id=my-amf) or from a token properties file specified via 
+ * token.file JVM property (eg. -Dtoken.file=/usr/local/tokens.properties) where
+ * the token key and value are specified in the property file.
+ * 
+ * If a token value is both specified as a JVM property and inside the token.file,
+ * JVM property takes precedence.
+ *
+ *
+ */
+public class TokenReplacer
+{
+    private static final String TOKEN_FILE = "token.file";
+    private static final Pattern pattern = Pattern.compile("\\{(.*?)\\}");
+
+    private final Map replacedTokens;
+    private Properties tokenProperties;
+    private String tokenPropertiesFilename;
+
+    /**
+     * Default constructor.
+     */
+    public TokenReplacer()
+    {
+        replacedTokens = new LinkedHashMap();
+        loadTokenProperties();
+    }
+
+    /**
+     * Replace any tokens in the value of the node or the text child of the node.
+     *
+     * @param node The node whose value will be searched for tokens.
+     * @param sourceFileName The source file where the node came from.
+     */
+    public void replaceToken(Node node, String sourceFileName)
+    {
+        // Exit if we are attempting to replace one of the forbidden nodes - nodes
+        // that may have curly brackets as part of their syntax
+        if (ConfigurationConstants.IP_ADDRESS_PATTERN.equals(node.getNodeName()))
+            return;
+
+        // ReplacementNode is either the original node if it has a value or the text
+        // child of the node if it does not have a value
+        Node replacementNode;
+        if (node.getNodeValue() == null)
+        {
+            if (node.getChildNodes().getLength() == 1 && node.getFirstChild() instanceof Text)
+                replacementNode = node.getFirstChild();
+            else
+                return;
+        }
+        else
+        {
+            replacementNode = node;
+        }
+
+        String nodeValue = replacementNode.getNodeValue();
+        Matcher matcher = pattern.matcher(nodeValue);
+        while (matcher.find()) // Means the node value has token(s)
+        {
+            String tokenWithCurlyBraces = matcher.group();
+            String tokenWithoutCurlyBraces = matcher.group(1);
+            String propertyValue = getPropertyValue(tokenWithoutCurlyBraces);
+            if (propertyValue != null)
+            {
+                nodeValue = StringUtils.substitute(nodeValue, tokenWithCurlyBraces, propertyValue);
+                replacedTokens.put(tokenWithCurlyBraces, propertyValue);
+            }
+            // context-path, server-name and server-port tokens can be replaced
+            // later, therefore, no warning is necessary if they cannot be replaced
+            // at this point.
+            else if (!ConfigurationConstants.CONTEXT_PATH_TOKEN.equals(tokenWithCurlyBraces)
+                    && !ConfigurationConstants.CONTEXT_PATH_ALT_TOKEN.equals(tokenWithCurlyBraces)
+                    && !ConfigurationConstants.SERVER_NAME_TOKEN.equals(tokenWithCurlyBraces)
+                    && !ConfigurationConstants.SERVER_PORT_TOKEN.equals(tokenWithCurlyBraces))
+            {
+                // Token ''{0}'' in ''{1}'' was not replaced. Either supply a value to this token with a JVM option, or remove it from the configuration.
+                ConfigurationException ex = new ConfigurationException();
+                Object[] args = {tokenWithCurlyBraces, sourceFileName};
+                ex.setMessage(ConfigurationConstants.IRREPLACABLE_TOKEN, args);
+                throw ex;
+            }
+        }
+        replacementNode.setNodeValue(nodeValue);
+    }
+
+    /**
+     * See if the token have a value either provided as a JVM property or as 
+     * part of the token property file. JVM property takes precedence on the token
+     * property file.
+     */
+    private String getPropertyValue(String tokenWithoutCurlyBraces)
+    {
+        String propertyValue = System.getProperty(tokenWithoutCurlyBraces);
+        if (propertyValue != null)
+            return propertyValue;
+
+        if (tokenProperties != null)
+            propertyValue = tokenProperties.getProperty(tokenWithoutCurlyBraces);
+
+        return propertyValue;
+    }
+
+    /**
+     * Used by the parser to report the replaced tokens once logging is setup.
+     */
+    public void reportTokens()
+    {
+        if (Log.isWarn())
+        {
+            if (tokenProperties != null && Log.isDebug())
+                Log.getLogger(LogCategories.CONFIGURATION).debug("Token replacer is using the token file '" + tokenPropertiesFilename + "'");
+
+            for (Iterator iter = replacedTokens.entrySet().iterator(); iter.hasNext();)
+            {
+                Map.Entry entry = (Map.Entry)iter.next();
+                String tokenWithParanthesis = (String)entry.getKey();
+                String propertyValue = (String)entry.getValue();
+                // Issue a special warning for context.root replacements,
+                if (ConfigurationConstants.CONTEXT_PATH_TOKEN.equals(tokenWithParanthesis)
+                        || ConfigurationConstants.CONTEXT_PATH_ALT_TOKEN.equals(tokenWithParanthesis))
+                {
+                    Log.getLogger(LogCategories.CONFIGURATION).warn("Token '{0}' was replaced with '{1}'. Note that this will apply to all applications on the JVM",
+                            new Object[]{tokenWithParanthesis, propertyValue});
+                }
+                else if (Log.isDebug())
+                {
+                    Log.getLogger(LogCategories.CONFIGURATION).debug("Token '{0}' was replaced with '{1}'", new Object[]{tokenWithParanthesis, propertyValue});
+                }
+            }
+        }
+    }
+
+    /**
+     * Given a String, determines whether the string contains tokens. 
+     * 
+     * @param value The String to check.
+     * @return True if the String contains tokens.
+     */
+    public static boolean containsTokens(String value)
+    {
+        return (value != null && value.length() > 0)? pattern.matcher(value).find() : false;
+    }
+
+    private void loadTokenProperties()
+    {
+        tokenPropertiesFilename = System.getProperty(TOKEN_FILE);
+        if (tokenPropertiesFilename == null)
+            return;
+
+        tokenProperties = new Properties();
+        try
+        {
+            tokenProperties.load(new FileInputStream(tokenPropertiesFilename));
+        }
+        catch (FileNotFoundException e)
+        {
+            tokenProperties = null;
+        }
+        catch (IOException e)
+        {
+            tokenProperties = null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/config/XPathClientConfigurationParser.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/config/XPathClientConfigurationParser.java b/common/src/main/java/flex/messaging/config/XPathClientConfigurationParser.java
new file mode 100644
index 0000000..2495754
--- /dev/null
+++ b/common/src/main/java/flex/messaging/config/XPathClientConfigurationParser.java
@@ -0,0 +1,89 @@
+/*
+ * 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.config;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+/**
+ * Uses Sun's JDK 1.5 XPath implementation on a DOM
+ * representation of a messaging configuration file.
+ * <p>
+ * NOTE: Since reference ids are used between elements, certain
+ * sections of the document need to be parsed first.
+ * </p>
+ *
+ *
+ */
+public class XPathClientConfigurationParser extends ClientConfigurationParser
+{
+    private XPath xpath;
+
+    protected void initializeExpressionQuery()
+    {
+        this.xpath = XPathFactory.newInstance().newXPath();
+    }
+
+    protected Node selectSingleNode(Node source, String expression)
+    {
+        try
+        {
+            return (Node) xpath.evaluate(expression, source, XPathConstants.NODE);
+        }
+        catch (XPathExpressionException expressionException)
+        {
+            throw wrapException(expressionException);
+        }
+    }
+
+    protected NodeList selectNodeList(Node source, String expression)
+    {
+        try
+        {
+            return (NodeList) xpath.evaluate(expression, source, XPathConstants.NODESET);
+        }
+        catch (XPathExpressionException expressionException)
+        {
+            throw wrapException(expressionException);
+        }
+    }
+
+    protected Object evaluateExpression(Node source, String expression)
+    {
+        try
+        {
+            return xpath.evaluate(expression, source, XPathConstants.STRING);
+        }
+        catch (XPathExpressionException expressionException)
+        {
+            throw wrapException(expressionException);
+        }
+    }
+
+    private ConfigurationException wrapException(XPathExpressionException exception)
+    {
+       ConfigurationException result = new ConfigurationException();
+       result.setDetails(PARSER_INTERNAL_ERROR);
+       result.setRootCause(exception);
+       return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/log/AbstractTarget.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/log/AbstractTarget.java b/common/src/main/java/flex/messaging/log/AbstractTarget.java
new file mode 100644
index 0000000..25e7040
--- /dev/null
+++ b/common/src/main/java/flex/messaging/log/AbstractTarget.java
@@ -0,0 +1,272 @@
+/*
+ * 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.LocalizedException;
+import flex.messaging.config.ConfigMap;
+import flex.messaging.util.UUIDUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ */
+public abstract class AbstractTarget implements Target
+{
+    private static final int INVALID_FILTER_CHARS = 10016;
+    private static final int INVALID_FILTER_STAR = 10017;
+
+    protected final String id;
+    protected List filters;
+    protected volatile short level;
+    protected volatile int loggerCount;
+    private final Object lock = new Object();
+    private boolean usingDefaultFilter = false;
+
+    //--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     * Default constructor.
+     */
+    public AbstractTarget()
+    {
+        id = UUIDUtils.createUUID();
+        level = LogEvent.ERROR;
+        filters = new ArrayList();
+        filters.add("*");
+        usingDefaultFilter = true;
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    // Initialize, validate, start, and stop methods.
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     * Initializes the target with id and properties. Subclasses can overwrite.
+     *
+     * @param id id for the target which is ignored.
+     * @param properties ConfigMap of properties for the target.
+     */
+    public void initialize(String id, ConfigMap properties)
+    {
+        // No-op
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    // Public Getters and Setters for AbstractTarget properties
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     * Return a read-only snap-shot of the current filters for this target.
+     *
+     * @return An unmodifiable list of filters.
+     */
+    public List getFilters()
+    {
+        return Collections.unmodifiableList(new ArrayList(filters));
+    }
+
+    /**
+     * Adds a filter to this target.
+     *
+     * @param value Filter to be added.
+     */
+    public void addFilter(String value)
+    {
+        if (value != null)
+            validateFilter(value);
+        else // Default to "*"
+            value = "*";
+
+        boolean filterWasAdded = false;
+        synchronized (lock)
+        {
+            if (!filters.contains(value))
+            {
+                // If the default filter is being used, remove it.
+                if (usingDefaultFilter)
+                {
+                    removeFilter("*");
+                    usingDefaultFilter = false;
+                }
+                filters.add(value);
+                filterWasAdded = true;
+            }
+        }
+        if (filterWasAdded)
+            Log.processTargetFilterAdd(this, value);
+    }
+
+    /**
+     * Removes a filter from this target.
+     *
+     * @param value Filter to be removed.
+     */
+    public void removeFilter(String value)
+    {
+        boolean filterWasRemoved;
+        synchronized (lock)
+        {
+            filterWasRemoved = filters.remove(value);
+        }
+        if (filterWasRemoved)
+            Log.processTargetFilterRemove(this, value);
+    }
+
+    /**
+     * Sets the list of filters for this target.
+     *
+     * @param value List of filters.
+     */
+    public void setFilters(List value)
+    {
+        if (value != null && value.size() > 0)
+        {
+            // a valid filter value will be fully qualified or have a wildcard
+            // in it.  the wild card can only be located at the end of the
+            // expression.  valid examples  xx*, xx.*,  *
+            for (int i = 0; i < value.size(); i++)
+            {
+                validateFilter((String) value.get(i));
+            }
+        }
+        else
+        {
+            // if null was specified then default to all
+            value = new ArrayList();
+            value.add("*");
+        }
+
+        Log.removeTarget(this);
+        synchronized (lock)
+        {
+            filters = value;
+            usingDefaultFilter = false;
+        }
+        Log.addTarget(this);
+    }
+
+    /**
+     * Return the log level for this target.
+     *
+     * @return the log level set for this target.
+     */
+    public short getLevel()
+    {
+        return level;
+    }
+
+    /**
+     * Return the target's unique ID.
+     *
+     * @return the target's unique ID.
+     */
+    public String getId()
+    {
+        return id;
+    }
+
+    /**
+     * Sets the log level for this target. If not set, defaults to <code>LogEvent.ERROR</code>.
+     */
+    public void setLevel(short value)
+    {
+        level = value;
+        Log.resetTargetLevel();
+    }
+
+    /**
+     * Sets up this target with the specified logger.
+     * This allows this target to receive log events from the specified logger.
+     *
+     * @param logger this target should listen to.
+     */
+    public void addLogger(Logger logger)
+    {
+        if (logger != null)
+        {
+            synchronized (lock)
+            {
+                loggerCount++;
+            }
+            logger.addTarget(this);
+        }
+    }
+
+    /**
+     * Stops this target from receiving events from the specified logger.
+     *
+     * @param logger this target should ignore.
+     */
+    public void removeLogger(Logger logger)
+    {
+        if (logger != null)
+        {
+            synchronized (lock)
+            {
+                loggerCount--;
+            }
+            logger.removeTarget(this);
+        }
+    }
+
+    /**
+     * @param filter category to check against the filters defined for this target
+     * @return whether filter is defined
+     */
+    public boolean containsFilter(String filter)
+    {
+        return filters.contains(filter);
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    // Protected/private methods.
+    //
+    //--------------------------------------------------------------------------
+
+    private void validateFilter(String value)
+    {
+        // check for invalid characters
+        if (Log.hasIllegalCharacters(value))
+        {
+            //Error for filter '{filter}'. The following characters are not valid: {Log.INVALID_CHARS}
+            LocalizedException ex = new LocalizedException();
+            ex.setMessage(INVALID_FILTER_CHARS, new Object[]{value, Log.INVALID_CHARS});
+            throw ex;
+        }
+
+        int index = value.indexOf('*');
+        if ((index >= 0) && (index != (value.length() - 1)))
+        {
+            //Error for filter '{filter}'. '*' must be the right most character.
+            LocalizedException ex = new LocalizedException();
+            ex.setMessage(INVALID_FILTER_STAR, new Object[]{value});
+            throw ex;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-blazeds/blob/8315f8fa/common/src/main/java/flex/messaging/log/ConsoleTarget.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/flex/messaging/log/ConsoleTarget.java b/common/src/main/java/flex/messaging/log/ConsoleTarget.java
new file mode 100644
index 0000000..b9faf76
--- /dev/null
+++ b/common/src/main/java/flex/messaging/log/ConsoleTarget.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+/**
+ *
+ */
+public class ConsoleTarget extends LineFormattedTarget
+{
+    //--------------------------------------------------------------------------
+    //
+    // Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     * Default constructor.
+     */
+    public ConsoleTarget()
+    {
+        super();
+    }
+
+    protected void internalLog(String message)
+    {
+        System.out.println(message);
+    }
+}