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 "whitelist"
+ * 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);
+ }
+}