You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by hi...@apache.org on 2009/07/15 08:26:57 UTC

svn commit: r794151 - in /synapse/trunk/java/modules/core/src/main/java/org/apache/synapse: config/ config/xml/ core/axis2/ endpoints/ eventing/ mediators/base/ startup/

Author: hiranya
Date: Wed Jul 15 06:26:57 2009
New Revision: 794151

URL: http://svn.apache.org/viewvc?rev=794151&view=rev
Log:
Adding the new multi XML configuration builder which initializes the Synapse configuration by processing a specified file hierarchy. The associated configuration serializer is also included. The following changes were made in the existing code to accomodate the new configuration builder.

* All Synapse deployment artifacts (proxy services, sequences, endpoints etc) now has a data member called 'fileName' which is by default initialized to null. This field can be used to store the name of the file where the corresponding artifact was defined. Getter/setter methods required to access the field are also provided.

* define* methods in the SynapseXMLConfigurationFactory now return the objects they create and add to the Synapse configuration. This enables custom configuration builders to manipulate Synapse configuration elements at configuration build time.

* The SynapseConfigurationBuilder checks whether the specified synapse xml is a file or a directory and calls the appropriate configuration builder.

Note that this addition does not alter the existing functionality and th configuration model at all. synapse.xml based configuration model is still supported and is the default method of configuring synapse.



Added:
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationBuilder.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationSerializer.java
Modified:
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/Entry.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/SynapseConfigurationBuilder.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/SynapseXMLConfigurationFactory.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/ProxyService.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/eventing/SynapseEventSource.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/base/SequenceMediator.java
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/startup/AbstractStartup.java

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/Entry.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/Entry.java?rev=794151&r1=794150&r2=794151&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/Entry.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/Entry.java Wed Jul 15 06:26:57 2009
@@ -48,6 +48,8 @@
     private long version;
     /** The local expiry time for the cached resource */
     private long expiryTime;
+    /** The name of the file where this entry is defined */
+    private String fileName;
 
     public Entry() {}
     
@@ -145,6 +147,14 @@
         this.expiryTime = expiryTime;
     }
 
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
     public boolean isExpired() {
         return getType() == REMOTE_ENTRY && getExpiryTime() > 0
                 && System.currentTimeMillis() > expiryTime;

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/SynapseConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/SynapseConfigurationBuilder.java?rev=794151&r1=794150&r2=794151&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/SynapseConfigurationBuilder.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/SynapseConfigurationBuilder.java Wed Jul 15 06:26:57 2009
@@ -24,10 +24,13 @@
 import org.apache.synapse.SynapseConstants;
 import org.apache.synapse.SynapseException;
 import org.apache.synapse.config.xml.XMLConfigurationBuilder;
+import org.apache.synapse.config.xml.MultiXMLConfigurationBuilder;
+import org.apache.synapse.config.xml.MultiXMLConfigurationSerializer;
 import org.apache.synapse.mediators.base.SequenceMediator;
 import org.apache.synapse.mediators.builtin.DropMediator;
 import org.apache.synapse.mediators.builtin.LogMediator;
 
+import javax.xml.stream.XMLStreamException;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -64,25 +67,41 @@
     /**
      * Build a Synapse configuration from a given XML configuration file
      *
-     * @param configFile the XML configuration
+     * @param configFile Path to the Synapse configuration file or directory
      * @return the Synapse configuration model
      */
     public static SynapseConfiguration getConfiguration(String configFile) {
 
-        // build the Synapse configuration parsing the XML config file
-        try {
-            SynapseConfiguration synCfg
-                    = XMLConfigurationBuilder.getConfiguration(new FileInputStream(configFile));
-            log.info("Loaded Synapse configuration from : " + configFile);
-            synCfg.setPathToConfigFile(new File(configFile).getAbsolutePath());
-            return synCfg;
-
-        } catch (FileNotFoundException fnf) {
-            handleException("Cannot load Synapse configuration from : " + configFile, fnf);
-        } catch (Exception e) {
-            handleException("Could not initialize Synapse : " + e.getMessage(), e);
+        File synapseConfigLocation = new File(configFile);
+        if (!synapseConfigLocation.exists()) {
+            throw new SynapseException("Unable to load the Synapse configuration from : " + configFile);
         }
-        return null;
+
+        SynapseConfiguration synCfg = null;
+        if (synapseConfigLocation.isFile()) {
+            // build the Synapse configuration parsing the XML config file
+            try {
+                synCfg = XMLConfigurationBuilder.getConfiguration(new FileInputStream(configFile));
+                log.info("Loaded Synapse configuration from : " + configFile);
+                synCfg.setPathToConfigFile(new File(configFile).getAbsolutePath());
+            } catch (Exception e) {
+                handleException("Could not initialize Synapse : " + e.getMessage(), e);
+            }
+
+        } else if (synapseConfigLocation.isDirectory()) {
+            // build the Synapse configuration by processing given directory hierarchy
+            try {
+                synCfg = MultiXMLConfigurationBuilder.getConfiguration(configFile);
+                log.info("Loaded Synapse configuration from the directory hierarchy at : " + configFile);
+                MultiXMLConfigurationSerializer s = new MultiXMLConfigurationSerializer("/home/hiranya/Desktop/myconf");
+                s.serialize(synCfg);
+            } catch (XMLStreamException e) {
+                handleException("Could not initialize Synapse : " + e.getMessage(), e);
+            }
+        }
+
+
+        return synCfg;
     }
 
     private static void handleException(String msg, Exception e) {

Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationBuilder.java?rev=794151&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationBuilder.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationBuilder.java Wed Jul 15 06:26:57 2009
@@ -0,0 +1,306 @@
+/*
+ *  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 org.apache.synapse.config.xml;
+
+import org.apache.synapse.config.SynapseConfiguration;
+import org.apache.synapse.config.SynapseConfigUtils;
+import org.apache.synapse.config.Entry;
+import org.apache.synapse.SynapseException;
+import org.apache.synapse.Startup;
+import org.apache.synapse.Mediator;
+import org.apache.synapse.eventing.SynapseEventSource;
+import org.apache.synapse.endpoints.Endpoint;
+import org.apache.synapse.endpoints.AbstractEndpoint;
+import org.apache.synapse.mediators.base.SequenceMediator;
+import org.apache.synapse.startup.AbstractStartup;
+import org.apache.synapse.core.axis2.ProxyService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNode;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.namespace.QName;
+import java.io.*;
+import java.util.Iterator;
+
+/**
+ * <p>
+ * This optional configuration builder creates the Synapse configuration by processing
+ * a specified file hierarchy. If the root of the specified file hierarchy is CONF_HOME,
+ * then the following directories are expected to be in CONF_HOME.
+ * <ul>
+ *  <li>CONF_HOME/proxy-services</li>
+ *  <li>CONF_HOME/sequences</li>
+ *  <li>CONF_HOME/endpoints</li>
+ *  <li>CONF_HOME/local-entries</li>
+ *  <li>CONF_HOME/tasks</li>
+ *  <li>CONF_HOME/events</li>
+ * </ul>
+ *
+ * Each of these directories will house a set of XML files. Each file will define exactly
+ * one configuration item (eg: a proxy service, an endpoint, a sequence).
+ * </p>
+ * <p>
+ * In addition to the directories mentioned above one can have the following two files in
+ * CONF_HOME
+ * <ul>
+ *  <li>CONF_HOME/registry.xml</li>
+ *  <li>CONF_HOME/local-entries.xml</li>
+ * </ul>
+ * </p>
+ *
+ */
+public class MultiXMLConfigurationBuilder {
+
+    public static final String PROXY_SERVICES_DIR  = "proxy-services";
+    public static final String SEQUENCES_DIR       = "sequences";
+    public static final String ENDPOINTS_DIR       = "endpoints";
+    public static final String LOCAL_ENTRY_DIR     = "local-entries";
+    public static final String TASKS_DIR           = "tasks";
+    public static final String EVENTS_DIR          = "events";
+
+    public static final String REGISTRY_FILE       = "registry.xml";
+    public static final String LOCAL_ENTRIES_FILE  = "local-entries.xml";
+
+    public static final String LOCAL_ENTRIES_ROOT_ELT  = "localEntries";
+
+    public static final String LOCAL_ENTRIES_FILE_ID   =  "LocalEntries*?";
+
+    public static Log log = LogFactory.getLog(MultiXMLConfigurationBuilder.class);
+
+    private static FileFilter filter = new FileFilter() {
+        public boolean accept(File pathname) {
+            return (pathname.isFile() && pathname.getName().endsWith(".xml"));
+        }
+    };
+
+    public static SynapseConfiguration getConfiguration(String root) throws XMLStreamException {
+
+        if (log.isDebugEnabled()) {
+            log.debug("Building Synapse configuration from the directory heirarchy at : " + root);
+        }
+
+        SynapseConfiguration synapseConfig = new SynapseConfiguration();
+        synapseConfig.setDefaultQName(XMLConfigConstants.DEFINITIONS_ELT);
+
+        try {
+            createRegistry(synapseConfig, root);
+            createLocalEntries(synapseConfig, root);
+            createEndpoints(synapseConfig, root);
+            createSequences(synapseConfig, root);
+            createProxyServices(synapseConfig, root);
+            createTasks(synapseConfig, root);
+            createEventSources(synapseConfig, root);
+
+        } catch (FileNotFoundException e) {
+            handleException("Error while reading from configuration file", e);
+        }
+
+        if (synapseConfig.getLocalRegistry().isEmpty() && synapseConfig.getProxyServices().isEmpty()
+                && synapseConfig.getRegistry() != null) {
+
+            log.info("No proxy service definitions or local entry definitions were found at : " + root + ". " +
+                    "Attempting to load the configuration from the Synapse registry.");
+            OMNode remoteConfigNode = synapseConfig.getRegistry().lookup("synapse.xml");
+            if (remoteConfigNode != null) {
+                synapseConfig = XMLConfigurationBuilder.getConfiguration(
+                        SynapseConfigUtils.getStreamSource(remoteConfigNode).getInputStream());
+            } else {
+                log.warn("The resource synapse.xml is not available in the Synapse registry.");
+            }
+        }
+
+        // after all, if there is no sequence named main defined attach a default one
+        if (synapseConfig.getMainSequence() == null) {
+            log.info("Creating the default main sequence");
+            SynapseXMLConfigurationFactory.setDefaultMainSequence(synapseConfig);
+        }
+
+        // after all, if there is no sequence named fault defined attach a default one
+        if (synapseConfig.getFaultSequence() == null) {
+            log.info("Creating the default fault sequence");
+            SynapseXMLConfigurationFactory.setDefaultFaultSequence(synapseConfig);
+        }
+        return synapseConfig;
+    }
+
+    private static void createRegistry(SynapseConfiguration synapseConfig,
+                                         String rootDirPath) throws FileNotFoundException, XMLStreamException {
+
+        File registryDef = new File(rootDirPath, REGISTRY_FILE);
+        if (registryDef.exists()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Initializing Synapse registry from the configuration at : " + registryDef.getPath());
+            }
+            OMElement document = parseFile(registryDef);
+            SynapseXMLConfigurationFactory.defineRegistry(synapseConfig, document);
+        }
+    }
+
+    private static void createLocalEntries(SynapseConfiguration synapseConfig,
+                                         String rootDirPath) throws FileNotFoundException, XMLStreamException {
+
+        File localEntriesDef = new File(rootDirPath, LOCAL_ENTRIES_FILE);
+        if (localEntriesDef.exists()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Loading local entry definitions from : " + localEntriesDef.getPath());
+            }
+            OMElement document = parseFile(localEntriesDef);
+            if (!document.getQName().equals(new QName(XMLConfigConstants.SYNAPSE_NAMESPACE, LOCAL_ENTRIES_ROOT_ELT))) {
+                throw new SynapseException("Invalid root element in the " + LOCAL_ENTRIES_FILE + " file. The local " +
+                        "entries definition file must have the root element : " + LOCAL_ENTRIES_ROOT_ELT);
+            }
+
+            Iterator childEntires = document.getChildren();
+            while (childEntires.hasNext()) {
+                Object o = childEntires.next();
+                if (o instanceof OMElement) {
+                    OMElement localEntry = (OMElement) o;
+                    if (XMLConfigConstants.ENTRY_ELT.equals(localEntry.getQName())) {
+                        Entry entry = SynapseXMLConfigurationFactory.defineEntry(synapseConfig, localEntry);
+                        entry.setFileName(LOCAL_ENTRIES_FILE_ID);
+                    } else {
+                        log.warn("Invalid element " + localEntry.getLocalName() + " in the " +
+                                LOCAL_ENTRIES_FILE + " file");
+                    }
+                }
+            }
+        }
+
+        File localEntriesDir = new File(rootDirPath, LOCAL_ENTRY_DIR);
+        if (localEntriesDir.exists()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Loading local entry definitions from : " + localEntriesDir.getPath());
+            }
+            File[] entryDefinitions = localEntriesDir.listFiles(filter);
+            for (File file : entryDefinitions) {
+                OMElement document = parseFile(file);
+                Entry entry = SynapseXMLConfigurationFactory.defineEntry(synapseConfig, document);
+                entry.setFileName(file.getName());
+            }
+        }
+
+    }
+
+    private static void createProxyServices(SynapseConfiguration synapseConfig,
+                                         String rootDirPath) throws FileNotFoundException, XMLStreamException {
+
+        File proxyServicesDir = new File(rootDirPath, PROXY_SERVICES_DIR);
+        if (proxyServicesDir.exists()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Loading proxy services from : " + proxyServicesDir.getPath());
+            }
+            File[] proxyDefinitions = proxyServicesDir.listFiles(filter);
+            for (File file : proxyDefinitions) {
+                OMElement document = parseFile(file);
+                ProxyService proxy = SynapseXMLConfigurationFactory.defineProxy(synapseConfig, document);
+                proxy.setFileName(file.getName());
+            }
+        }
+    }
+
+    private static void createTasks(SynapseConfiguration synapseConfig,
+                                         String rootDirPath) throws FileNotFoundException, XMLStreamException {
+
+        File tasksDir = new File(rootDirPath, TASKS_DIR);
+        if (tasksDir.exists()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Loading tasks from : " + tasksDir.getPath());
+            }
+            File[] taskDefinitions = tasksDir.listFiles(filter);
+            for (File file : taskDefinitions) {
+                OMElement document = parseFile(file);
+                Startup startup = SynapseXMLConfigurationFactory.defineStartup(synapseConfig, document);
+                if (startup instanceof AbstractStartup) {
+                    ((AbstractStartup) startup).setFileName(file.getName());
+                }
+            }
+        }
+    }
+
+    private static void createSequences(SynapseConfiguration synapseConfig,
+                                       String rootDirPath) throws FileNotFoundException, XMLStreamException {
+
+        File sequencesDir = new File(rootDirPath, SEQUENCES_DIR);
+        if (sequencesDir.exists()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Loading sequences from : " + sequencesDir.getPath());
+            }
+            File[] sequences = sequencesDir.listFiles(filter);
+            for (File file : sequences) {
+                OMElement document = parseFile(file);
+                Mediator seq = SynapseXMLConfigurationFactory.defineSequence(synapseConfig, document);
+                if (seq instanceof SequenceMediator) {
+                    ((SequenceMediator) seq).setFileName(file.getName());
+                }
+            }
+        }
+    }
+
+    private static void createEndpoints(SynapseConfiguration synapseConfig,
+                                       String rootDirPath) throws FileNotFoundException, XMLStreamException {
+
+        File endpointsDir = new File(rootDirPath, ENDPOINTS_DIR);
+        if (endpointsDir.exists()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Loading endpoints from : " + endpointsDir.getPath());
+            }
+            File[] endpoints = endpointsDir.listFiles(filter);
+            for (File file : endpoints) {
+                OMElement document = parseFile(file);
+                Endpoint endpoint = SynapseXMLConfigurationFactory.defineEndpoint(synapseConfig, document);
+                if (endpoint instanceof AbstractEndpoint) {
+                    ((AbstractEndpoint) endpoint).setFileName(file.getName());
+                }
+            }
+        }
+    }
+
+    private static void createEventSources(SynapseConfiguration synapseConfig,
+                                       String rootDirPath) throws FileNotFoundException, XMLStreamException {
+
+        File eventsDir = new File(rootDirPath, EVENTS_DIR);
+        if (eventsDir.exists()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Loading event sources from : " + eventsDir.getPath());
+            }
+            File[] events = eventsDir.listFiles(filter);
+            for (File file : events) {
+                OMElement document = parseFile(file);
+                SynapseEventSource eventSource = SynapseXMLConfigurationFactory.defineEventSource(
+                        synapseConfig, document);
+                eventSource.setFileName(file.getName());
+           }
+        }
+    }
+
+    private static OMElement parseFile(File file) throws FileNotFoundException, XMLStreamException {
+        InputStream is = new FileInputStream(file);
+        OMElement document = new StAXOMBuilder(is).getDocumentElement();
+        document.build();
+        return document;
+    }
+
+    private static void handleException(String msg, Exception e) {
+        log.error(msg, e);
+        throw new SynapseException(msg, e);
+    }
+}
\ No newline at end of file

Added: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationSerializer.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationSerializer.java?rev=794151&view=auto
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationSerializer.java (added)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MultiXMLConfigurationSerializer.java Wed Jul 15 06:26:57 2009
@@ -0,0 +1,414 @@
+/*
+ *  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 org.apache.synapse.config.xml;
+
+import org.apache.synapse.config.SynapseConfiguration;
+import org.apache.synapse.config.Entry;
+import org.apache.synapse.config.xml.eventing.EventSourceSerializer;
+import org.apache.synapse.config.xml.endpoints.EndpointSerializer;
+import org.apache.synapse.registry.Registry;
+import org.apache.synapse.core.axis2.ProxyService;
+import org.apache.synapse.eventing.SynapseEventSource;
+import org.apache.synapse.Startup;
+import org.apache.synapse.SynapseConstants;
+import org.apache.synapse.endpoints.Endpoint;
+import org.apache.synapse.endpoints.AbstractEndpoint;
+import org.apache.synapse.mediators.base.SequenceMediator;
+import org.apache.synapse.startup.AbstractStartup;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.namespace.QName;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.GregorianCalendar;
+import java.util.Collection;
+
+/**
+ * Serializes the Synapse configuration to a specified directory
+ */
+public class MultiXMLConfigurationSerializer {
+
+    /** The directory to where the configuration should be serialized */
+    private File rootDirectory;
+    /** The backup directory to be created when the target directory already exists */
+    private File backupDirectory;
+
+    private static Log log = LogFactory.getLog(MultiXMLConfigurationSerializer.class);
+
+    public MultiXMLConfigurationSerializer(String directoryPath) {
+        rootDirectory = new File(directoryPath);
+    }
+
+    public void serialize(SynapseConfiguration synapseConfig) {
+        if (log.isDebugEnabled()) {
+            log.debug("Starting to serialize the Synapse configuration to the directory : " + rootDirectory);
+        }
+
+        try {
+            // TO start with clean up the existing configuration files
+            cleanUpDirectory();
+
+            // Serialize various elements in the SynapseConfiguration
+            if (synapseConfig.getRegistry() != null) {
+                serializeSynapseRegistry(synapseConfig.getRegistry());
+            }
+
+            Collection<ProxyService> proxyServices = synapseConfig.getProxyServices();
+            if (!proxyServices.isEmpty()) {
+                serializeProxyServices(proxyServices);
+            }
+
+            Collection<SynapseEventSource> eventSources = synapseConfig.getEventSources();
+            if (!eventSources.isEmpty()) {
+                serializeEventSources(eventSources);
+            }
+
+            Collection<Startup> tasks = synapseConfig.getStartups();
+            if (!tasks.isEmpty()) {
+                serializeTasks(tasks);
+            }
+
+            Collection localRegistryValues = synapseConfig.getLocalRegistry().values();
+            if (!localRegistryValues.isEmpty()) {
+                serializeLocalRegistryValues(localRegistryValues);
+            }
+
+            log.info("Done serializing the Synapse configuration to : " + rootDirectory.getPath());
+
+            // If a backup was created, clean it up
+            if (backupDirectory != null) {
+                log.info("Cleaning up the backup files at : " + backupDirectory.getPath());
+                deleteDirectory(backupDirectory);
+                backupDirectory = null;
+            }
+
+        } catch (Exception e) {
+            log.error("Error occured while serializing the Synapse configuration.", e);
+            // Attempt to perform a restore using the backups available
+            restoreBackup();
+        }
+    }
+
+    private void serializeSynapseRegistry(Registry registry) throws Exception {
+        OMElement registryElem = RegistrySerializer.serializeRegistry(null, registry);
+        File registryConf = new File(rootDirectory, MultiXMLConfigurationBuilder.REGISTRY_FILE);
+        if (log.isDebugEnabled()) {
+            log.debug("Serializing Synapse registry definition to : " + registryConf.getPath());
+        }
+
+        if (registryConf.createNewFile()) {
+            OutputStream out = new FileOutputStream(registryConf);
+            registryElem.serializeAndConsume(out);
+            out.flush();
+        } else {
+            throw new Exception("Error while creating the registry configuration file at : " +
+                    registryConf.getAbsolutePath());
+        }
+    }
+
+    private void serializeProxyServices(Collection<ProxyService> proxyServices) throws Exception {
+
+        File proxyDir = new File(rootDirectory, MultiXMLConfigurationBuilder.PROXY_SERVICES_DIR);
+        if (log.isDebugEnabled()) {
+            log.debug("Serializing Synapse proxy services to : " + proxyDir.getPath());
+        }
+
+        if (!proxyDir.mkdir()) {
+            throw new Exception("Error while creating the directory for proxy services : " +
+                    proxyDir.getAbsolutePath());
+        }
+
+        for (ProxyService service : proxyServices) {
+            File proxyFile;
+            OMElement proxyElem = ProxyServiceSerializer.serializeProxy(null, service);
+
+            if (service.getFileName() != null) {
+                proxyFile = new File(proxyDir, service.getFileName());
+            } else {
+                proxyFile = new File(proxyDir, service.getName() + ".xml");
+            }
+
+            if (proxyFile.createNewFile()) {
+                OutputStream out = new FileOutputStream(proxyFile);
+                proxyElem.serializeAndConsume(out);
+                out.flush();
+            } else {
+                throw new Exception("Error while creating the file : " + proxyFile.getAbsolutePath());
+            }
+        }
+    }
+
+    private void serializeEventSources(Collection<SynapseEventSource> eventSources) throws Exception {
+
+        File eventsDir = new File(rootDirectory, MultiXMLConfigurationBuilder.EVENTS_DIR);
+        if (log.isDebugEnabled()) {
+            log.debug("Serializing Synapse event sources to : " + eventsDir.getPath());
+        }
+
+        if (!eventsDir.mkdir()) {
+            throw new Exception("Error while creating the directory for events : " + eventsDir.getAbsolutePath());
+        }
+
+        for (SynapseEventSource source : eventSources) {
+            File eventSrcFile;
+            OMElement eventSrcElem = EventSourceSerializer.serializeEventSource(null, source);
+
+            if (source.getFileName() != null) {
+                eventSrcFile = new File(eventsDir, source.getFileName());
+            } else {
+                eventSrcFile = new File(eventsDir, source.getName() + ".xml");
+            }
+
+            if (eventSrcFile.createNewFile()) {
+                OutputStream out = new FileOutputStream(eventSrcFile);
+                eventSrcElem.serializeAndConsume(out);
+                out.flush();
+            } else {
+                throw new Exception("Error while creating the file : " + eventSrcFile.getAbsolutePath());
+            }
+        }
+    }
+
+    private void serializeTasks(Collection<Startup> tasks) throws Exception {
+
+        File tasksDir = new File(rootDirectory, MultiXMLConfigurationBuilder.TASKS_DIR);
+        if (log.isDebugEnabled()) {
+            log.debug("Serializing Synapse startup tasks to : " + tasksDir.getPath());
+        }
+
+        if (!tasksDir.mkdir()) {
+            throw new Exception("Error while creating the directory for tasks : " + tasksDir.getAbsolutePath());
+        }
+
+        for (Startup task : tasks) {
+            File taskFile;
+            OMElement taslElem = StartupFinder.getInstance().serializeStartup(null, task);
+
+            if (task instanceof AbstractStartup && ((AbstractStartup) task).getFileName() != null) {
+                taskFile = new File(tasksDir, ((AbstractStartup) task).getFileName());
+            } else {
+                taskFile = new File(tasksDir, task.getName() + ".xml");
+            }
+
+            if (taskFile.createNewFile()) {
+                OutputStream out = new FileOutputStream(taskFile);
+                taslElem.serializeAndConsume(out);
+                out.flush();
+            } else {
+                throw new Exception("Error while creating the file : " + taskFile.getAbsolutePath());
+            }
+        }
+    }
+
+    private void serializeSequence(SequenceMediator seq) throws Exception {
+        File seqDir = new File(rootDirectory, MultiXMLConfigurationBuilder.SEQUENCES_DIR);
+        if (!seqDir.exists()) {
+            if (!seqDir.mkdir()) {
+                throw new Exception("Error while creating the directory for sequences : " + seqDir.getAbsolutePath());
+            }
+        }
+
+        OMElement seqElem = MediatorSerializerFinder.getInstance().getSerializer(seq).serializeMediator(null, seq);
+        File seqFile;
+        if (seq.getFileName() != null) {
+            seqFile = new File(seqDir, seq.getFileName());
+        } else {
+            seqFile = new File(seqDir, seq.getName() + ".xml");
+        }
+
+        if (seqFile.createNewFile()) {
+            OutputStream out = new FileOutputStream(seqFile);
+            seqElem.serializeAndConsume(out);
+            out.flush();
+        } else {
+            throw new Exception("Error while creating the file : " + seqFile.getAbsolutePath());
+        }
+
+    }
+
+    private void serializeEndpoint(Endpoint epr) throws Exception {
+        File eprDir = new File(rootDirectory, MultiXMLConfigurationBuilder.ENDPOINTS_DIR);
+        if (!eprDir.exists()) {
+            if (!eprDir.mkdir()) {
+                throw new Exception("Error while creating the directory for endpoints : " + eprDir.getAbsolutePath());
+            }
+        }
+
+        OMElement eprElem = EndpointSerializer.getElementFromEndpoint(epr);
+        File eprFile;
+        if (epr instanceof AbstractEndpoint && ((AbstractEndpoint) epr).getFileName() != null) {
+            eprFile = new File(eprDir, ((AbstractEndpoint) epr).getFileName());
+        } else if (epr.getName() != null) {
+            eprFile = new File(eprDir, epr.getName() + ".xml");
+        } else {
+            eprFile = new File(eprDir, "endpoint_" + new GregorianCalendar().getTimeInMillis() + ".xml");
+        }
+
+        if (eprFile.createNewFile()) {
+            OutputStream out = new FileOutputStream(eprFile);
+            eprElem.serializeAndConsume(out);
+            out.flush();
+        } else {
+            throw new Exception("Error while creating the file : " + eprFile.getAbsolutePath());
+        }
+
+    }
+
+    private void serializeLocalRegistryValues(Collection localValues) throws Exception {
+
+        if (log.isDebugEnabled()) {
+            log.debug("Serializing the local registry values (sequences/endpoints/local entries)");
+        }
+
+        OMElement localEntriesRoot = null;
+        boolean entriesDirCreated = false;
+
+        for (Object o : localValues) {
+            if (o instanceof SequenceMediator) {
+                serializeSequence((SequenceMediator) o);
+            } else if (o instanceof Endpoint) {
+                serializeEndpoint((Endpoint) o);
+            } else if (o instanceof Entry) {
+                Entry entry = (Entry) o;
+                if ((SynapseConstants.SERVER_HOST.equals(entry.getKey())
+                        || SynapseConstants.SERVER_IP.equals(entry.getKey()))
+                        || entry.getType() == Entry.REMOTE_ENTRY) {
+                    continue;
+                }
+
+                if (MultiXMLConfigurationBuilder.LOCAL_ENTRIES_FILE_ID.equals(entry.getFileName())) {
+                    // If this entry comes from the top level local entry definition file we simply add this
+                    // OMElement to a paranet element
+                    if (localEntriesRoot == null) {
+                        localEntriesRoot = OMAbstractFactory.getSOAP11Factory().createOMElement(
+                                new QName(XMLConfigConstants.SYNAPSE_NAMESPACE,
+                                        MultiXMLConfigurationBuilder.LOCAL_ENTRIES_ROOT_ELT));
+                    }
+                    EntrySerializer.serializeEntry(entry, localEntriesRoot);
+
+                } else {
+                    File entriesDir = null;
+                    OMElement entryElem = EntrySerializer.serializeEntry(entry, null);
+                    if (!entriesDirCreated) {
+                        entriesDir = new File(rootDirectory, MultiXMLConfigurationBuilder.LOCAL_ENTRY_DIR);
+                        if (!entriesDir.mkdir()) {
+                            throw new Exception("Error while creating the local entries directory : " +
+                                    entriesDir.getAbsolutePath());
+                        }
+                        entriesDirCreated = true;
+                    }
+
+                    File entryFile;
+                    if (entry.getFileName() != null) {
+                       entryFile  = new File(entriesDir, entry.getFileName());
+                    } else {
+                        entryFile = new File(entriesDir, "entry_" + new GregorianCalendar().getTimeInMillis() + ".xml");
+                    }
+
+                    if (entryFile.createNewFile()) {
+                        OutputStream out = new FileOutputStream(entryFile);
+                        entryElem.serializeAndConsume(out);
+                        out.flush();
+                    } else {
+                        throw new Exception("Error while creating the file : " + entryFile.getAbsolutePath());
+                    }
+                }
+            }
+        }
+
+        if (localEntriesRoot != null) {
+            File entryFile = new File(rootDirectory, MultiXMLConfigurationBuilder.LOCAL_ENTRIES_FILE);
+            if (entryFile.createNewFile()) {
+                OutputStream out = new FileOutputStream(entryFile);
+                localEntriesRoot.serializeAndConsume(out);
+                out.flush();
+            } else {
+                throw new Exception("Error while creating file : " + entryFile.getAbsolutePath());
+            }
+        }
+    }
+
+    private void cleanUpDirectory()  throws Exception {
+        // If the target directory already exists and contains any files simply rename it to create a backup
+        // This method does not delete the target directory
+        if (rootDirectory.exists() && rootDirectory.isDirectory() &&
+                rootDirectory.listFiles().length > 0) {
+            if (log.isDebugEnabled()) {
+                log.debug("The directory :" + rootDirectory.getPath() + " already exists. Creating a backup.");
+            }
+
+            backupDirectory = new File(rootDirectory.getParentFile(), "__tmp" +
+                    new GregorianCalendar().getTimeInMillis());
+            if (!rootDirectory.renameTo(backupDirectory)) {
+                throw new Exception("Error occured while backing up the existing file structure at : " +
+                        rootDirectory.getAbsolutePath());
+            }
+        }
+
+        // Create a new target directory
+        if (!rootDirectory.mkdirs()) {
+            throw new Exception("Error while creating the directory at : " + rootDirectory.getAbsolutePath());
+        }
+    }
+
+    private void restoreBackup() {
+        if (backupDirectory != null) {
+            log.info("Attempting to restore the directory : " + rootDirectory.getPath() +
+                    " using the available backups");
+            if (rootDirectory.exists() && rootDirectory.isDirectory()) {
+                deleteDirectory(rootDirectory);
+            }
+
+            if (backupDirectory.renameTo(rootDirectory)) {
+                log.info("Successfully restored the directory at : " + rootDirectory.getPath());
+                backupDirectory = null;
+            } else {
+                log.error("Failed to restore the directory at : " + rootDirectory.getPath() +
+                        " from the available backup. You will need to restore the directory manually. A backup is" +
+                        "available at : " + backupDirectory.getPath());
+            }
+        }
+    }
+
+    private boolean deleteDirectory(File dir) {
+        if (log.isDebugEnabled()) {
+            log.debug("Deleting the file or directory : " + dir.getPath());
+        }
+
+        if (dir.isDirectory()) {
+            String[] children = dir.list();
+            for (String child : children) {
+                boolean success = deleteDirectory(new File(dir, child));
+                if (!success) {
+                    return false;
+                }
+            }
+        }
+
+        // The directory is now empty so delete it
+        return dir.delete();
+    }
+
+
+}
\ No newline at end of file

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/SynapseXMLConfigurationFactory.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/SynapseXMLConfigurationFactory.java?rev=794151&r1=794150&r2=794151&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/SynapseXMLConfigurationFactory.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/SynapseXMLConfigurationFactory.java Wed Jul 15 06:26:57 2009
@@ -29,7 +29,6 @@
 import org.apache.synapse.SynapseException;
 import org.apache.synapse.registry.Registry;
 import org.apache.synapse.aspects.AspectConfiguration;
-import org.apache.synapse.aspects.AspectConfigurable;
 import org.apache.synapse.eventing.SynapseEventSource;
 import org.apache.synapse.config.Entry;
 import org.apache.synapse.config.SynapseConfigUtils;
@@ -50,11 +49,11 @@
 import java.util.Iterator;
 
 public class SynapseXMLConfigurationFactory implements ConfigurationFactory {
-    
+
     private static Log log = LogFactory.getLog(SynapseXMLConfigurationFactory.class);
 
     public SynapseConfiguration getConfiguration(OMElement definitions) {
-        
+
         if (!definitions.getQName().equals(XMLConfigConstants.DEFINITIONS_ELT)) {
             throw new SynapseException(
                     "Wrong QName for this configuration factory " + definitions.getQName());
@@ -69,7 +68,7 @@
         AspectConfiguration configuration = new AspectConfiguration(rootSequence.getName());
         rootSequence.configure(configuration);
         Iterator iter = definitions.getChildren();
-        
+
         while (iter.hasNext()) {
             Object o = iter.next();
             if (o instanceof OMElement) {
@@ -109,7 +108,7 @@
             OMNode remoteConfigNode = localConfigReg.lookup("synapse.xml");
             try {
                 config = XMLConfigurationBuilder.getConfiguration(SynapseConfigUtils
-                    .getStreamSource(remoteConfigNode).getInputStream());
+                        .getStreamSource(remoteConfigNode).getInputStream());
                 if (config.getRegistry() == null) {
                     config.setRegistry(localConfigReg);
                 }
@@ -143,38 +142,43 @@
         return config;
     }
 
-    public static void defineRegistry(SynapseConfiguration config, OMElement elem) {
+    public static Registry defineRegistry(SynapseConfiguration config, OMElement elem) {
         if (config.getRegistry() != null) {
             handleException("Only one remote registry can be defined within a configuration");
         }
-        config.setRegistry(RegistryFactory.createRegistry(elem));
+        Registry registry = RegistryFactory.createRegistry(elem);
+        config.setRegistry(registry);
+        return registry;
     }
 
-    public static void defineStartup(SynapseConfiguration config, OMElement elem) {
+    public static Startup defineStartup(SynapseConfiguration config, OMElement elem) {
         Startup startup = StartupFinder.getInstance().getStartup(elem);
         if (config.getStartup(startup.getName()) != null) {
             handleException("Duplicate startup with name : " + startup.getName());
         }
         config.addStartup(startup);
+        return startup;
     }
 
-    public static void defineProxy(SynapseConfiguration config, OMElement elem) {
+    public static ProxyService defineProxy(SynapseConfiguration config, OMElement elem) {
         ProxyService proxy = ProxyServiceFactory.createProxy(elem);
         if (config.getProxyService(proxy.getName()) != null) {
             handleException("Duplicate proxy service with name : " + proxy.getName());
         }
         config.addProxyService(proxy.getName(), proxy);
+        return proxy;
     }
 
-    public static void defineEntry(SynapseConfiguration config, OMElement elem) {
+   public static Entry defineEntry(SynapseConfiguration config, OMElement elem) {
         Entry entry = EntryFactory.createEntry(elem);
         if (config.getLocalRegistry().get(entry.getKey()) != null) {
             handleException("Duplicate registry entry definition for key : " + entry.getKey());
         }
         config.addEntry(entry.getKey(), entry);
+       return entry;
     }
 
-    public static void defineSequence(SynapseConfiguration config, OMElement ele) {
+    public static Mediator defineSequence(SynapseConfiguration config, OMElement ele) {
 
         String name = ele.getAttributeValue(new QName(XMLConfigConstants.NULL_NAMESPACE, "name"));
         if (name != null) {
@@ -189,12 +193,14 @@
             if (SynapseConstants.MANDATORY_SEQUENCE_KEY.equals(name)) {
                 config.setMandatorySequence(mediator);
             }
+            return mediator;
         } else {
             handleException("Invalid sequence definition without a name");
         }
+        return null;
     }
 
-    public static void defineEndpoint(SynapseConfiguration config, OMElement ele) {
+    public static Endpoint defineEndpoint(SynapseConfiguration config, OMElement ele) {
 
         String name = ele.getAttributeValue(new QName(XMLConfigConstants.NULL_NAMESPACE, "name"));
         if (name != null) {
@@ -203,17 +209,20 @@
             }
             Endpoint endpoint = EndpointFactory.getEndpointFromElement(ele, false);
             config.addEndpoint(name.trim(), endpoint);
+            return endpoint;
         } else {
             handleException("Invalid endpoint definition without a name");
         }
+        return null;
     }
 
-   public static void defineEventSource(SynapseConfiguration config, OMElement elem) {
+    public static SynapseEventSource defineEventSource(SynapseConfiguration config, OMElement elem) {
         SynapseEventSource eventSource = EventSourceFactory.createEventSource(elem);
         if (config.getEventSource(eventSource.getName()) != null) {
             handleException("Duplicate proxy service with name : " + eventSource.getName());
         }
         config.addEventSource(eventSource.getName(), eventSource);
+        return eventSource;
     }
 
     /**
@@ -276,7 +285,7 @@
         // set aspect configuration
         AspectConfiguration configuration = new AspectConfiguration(fault.getName());
         fault.configure(configuration);
-        
+
         config.addSequence(org.apache.synapse.SynapseConstants.FAULT_SEQUENCE_KEY, fault);
     }
 

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/ProxyService.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/ProxyService.java?rev=794151&r1=794150&r2=794151&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/ProxyService.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/ProxyService.java Wed Jul 15 06:26:57 2009
@@ -202,6 +202,8 @@
 
     private AspectConfiguration aspectConfiguration;
 
+    private String fileName;
+
     /**
      * Constructor
      *
@@ -950,6 +952,14 @@
         return aspectConfiguration;
     }
 
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer();

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java?rev=794151&r1=794150&r2=794151&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/endpoints/AbstractEndpoint.java Wed Jul 15 06:26:57 2009
@@ -67,6 +67,9 @@
     /** The MBean managing the endpoint */
     EndpointView metricsMBean = null;
 
+    /** The name of the file where this endpoint is defined */
+    protected String fileName;
+
     protected AbstractEndpoint() {
         log = LogFactory.getLog(this.getClass());
     }
@@ -114,6 +117,14 @@
         this.children = children;
     }
 
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
     public String toString() {
         if (endpointName != null) {
             return "Endpoint [" + endpointName + "]";

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/eventing/SynapseEventSource.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/eventing/SynapseEventSource.java?rev=794151&r1=794150&r2=794151&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/eventing/SynapseEventSource.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/eventing/SynapseEventSource.java Wed Jul 15 06:26:57 2009
@@ -65,6 +65,7 @@
     private String name;
     private SubscriptionManager subscriptionManager;
     private static final Log log = LogFactory.getLog(SynapseEventSource.class);
+    private String fileName;
 
     public SynapseEventSource(String name) {
         this.name = name;
@@ -86,6 +87,14 @@
         this.subscriptionManager = subscriptionManager;
     }
 
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
+
     public void buildService(AxisConfiguration axisCfg) throws AxisFault {
         AxisService eventSourceService = new AxisService();
         eventSourceService.setName(this.name);

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/base/SequenceMediator.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/base/SequenceMediator.java?rev=794151&r1=794150&r2=794151&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/base/SequenceMediator.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/base/SequenceMediator.java Wed Jul 15 06:26:57 2009
@@ -53,7 +53,9 @@
     /** flag to ensure that each and every sequence is initialized and destroyed atmost once */
     private boolean initialized = false;
     /** the registry key to load this definition if dynamic */
-    private String registryKey = null;   
+    private String registryKey = null;
+    /** The name of the file where this sequence is defined */
+    private String fileName;
 
     /**
      * If this mediator refers to another named Sequence, execute that. Else
@@ -275,4 +277,12 @@
     public String getAuditId() {
         return getName();
     }
+
+    public String getFileName() {
+        return fileName;
+    }
+
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
 }

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/startup/AbstractStartup.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/startup/AbstractStartup.java?rev=794151&r1=794150&r2=794151&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/startup/AbstractStartup.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/startup/AbstractStartup.java Wed Jul 15 06:26:57 2009
@@ -32,6 +32,11 @@
     protected String name = null;
 
     /**
+     * Holds the name of the file where this startup is defined
+     */
+    protected String fileName;
+
+    /**
      * This will return the name of the startup
      *
      * @return String representing the name
@@ -49,4 +54,23 @@
     public void setName(String name) {
         this.name = name;
     }
+
+    /**
+     * Returns the name of the file where this startup is defined
+     *
+     * @return a file name as a string or null
+     */
+    public String getFileName() {
+        return fileName;
+    }
+
+
+    /**
+     * Set the name of the file name where this startup is defined
+     *
+     * @param fileName the name of the file as a string
+     */
+    public void setFileName(String fileName) {
+        this.fileName = fileName;
+    }
 }