[jboss-cvs] JBossAS SVN: r80058 - in trunk: system and 3 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Oct 24 13:03:53 EDT 2008


Author: emuckenhuber
Date: 2008-10-24 13:03:53 -0400 (Fri, 24 Oct 2008)
New Revision: 80058

Added:
   trunk/system/src/main/org/jboss/system/server/profileservice/attachments/
   trunk/system/src/main/org/jboss/system/server/profileservice/attachments/AttachmentMetaData.java
   trunk/system/src/main/org/jboss/system/server/profileservice/attachments/DeploymentClassPathMetaData.java
   trunk/system/src/main/org/jboss/system/server/profileservice/attachments/DeploymentStructureMetaData.java
   trunk/system/src/main/org/jboss/system/server/profileservice/attachments/JAXBAttachmentHelper.java
   trunk/system/src/main/org/jboss/system/server/profileservice/attachments/LazyPredeterminedManagedObjects.java
   trunk/system/src/main/org/jboss/system/server/profileservice/attachments/RepositoryAttachmentMetaData.java
   trunk/system/src/main/org/jboss/system/server/profileservice/attachments/RepositoryAttachmentMetaDataFactory.java
Modified:
   trunk/profileservice/src/main/org/jboss/profileservice/management/ManagementViewImpl.java
   trunk/system/.classpath
   trunk/system/build.xml
   trunk/system/src/main/org/jboss/system/server/profileservice/repository/SerializableDeploymentRepository.java
Log:
[JBAS-6037] restoring attachment persistence

Modified: trunk/profileservice/src/main/org/jboss/profileservice/management/ManagementViewImpl.java
===================================================================
--- trunk/profileservice/src/main/org/jboss/profileservice/management/ManagementViewImpl.java	2008-10-24 17:02:50 UTC (rev 80057)
+++ trunk/profileservice/src/main/org/jboss/profileservice/management/ManagementViewImpl.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -25,6 +25,7 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -43,9 +44,13 @@
 import org.jboss.aspects.security.SecurityClientInterceptor;
 import org.jboss.deployers.client.spi.Deployment;
 import org.jboss.deployers.client.spi.main.MainDeployer;
+import org.jboss.deployers.plugins.main.MainDeployerImpl;
 import org.jboss.deployers.spi.management.DeploymentTemplate;
 import org.jboss.deployers.spi.management.ManagementView;
 import org.jboss.deployers.spi.management.RuntimeComponentDispatcher;
+import org.jboss.deployers.spi.structure.ContextInfo;
+import org.jboss.deployers.spi.structure.StructureMetaData;
+import org.jboss.deployers.structure.spi.DeploymentContext;
 import org.jboss.deployers.vfs.spi.client.VFSDeployment;
 import org.jboss.deployers.vfs.spi.client.VFSDeploymentFactory;
 import org.jboss.logging.Logger;
@@ -83,6 +88,9 @@
 import org.jboss.profileservice.spi.ProfileKey;
 import org.jboss.profileservice.spi.ProfileService;
 import org.jboss.remoting.InvokerLocator;
+import org.jboss.system.server.profileservice.attachments.AttachmentMetaData;
+import org.jboss.system.server.profileservice.attachments.RepositoryAttachmentMetaData;
+import org.jboss.system.server.profileservice.attachments.RepositoryAttachmentMetaDataFactory;
 import org.jboss.virtual.VirtualFile;
 
 /**
@@ -841,8 +849,15 @@
    {
       // Find the comp deployment
       ManagedDeployment md = comp.getDeployment();
+      // Create the metadata
+      RepositoryAttachmentMetaData childMetaData = RepositoryAttachmentMetaDataFactory.createInstance(md);
+      RepositoryAttachmentMetaData parentMetaData = childMetaData;
+      // Get the parent
       while( md.getParent() != null )
+      {
          md = md.getParent();
+         parentMetaData = RepositoryAttachmentMetaDataFactory.createNewParent(md, parentMetaData);
+      }
       String name = md.getName();
       DeploymentPhase phase = md.getDeploymentPhase();
       VFSDeployment compDeployment = activeProfile.getDeployment(name, phase);
@@ -867,7 +882,7 @@
       else
       {
          // Look at the children
-         // TODO - support more levels of nested deployments 
+         // TODO - support more levels of nested deployments ?
          for(ManagedDeployment child : compMD.getChildren())
          {
             if(serverComp != null)
@@ -886,7 +901,7 @@
          throw new IllegalArgumentException(msg);
       }
 
-      // dispatch the values
+      // Dispatch any runtime component property values
       for(ManagedProperty prop : comp.getProperties().values())
       {
          // Skip null values && non-CONFIGURATION values
@@ -925,23 +940,82 @@
             dispatcher.set(componentName, ctxProp.getName(), metaValue);
       }
       
-      // Create attachments, based on the parent ManagedObject
-      Map<String, Object> attachments = new HashMap<String, Object>();
-      
-      ManagedCommon parent = comp;
+      // Get the parent ManagedCommon
+      ManagedCommon parent = serverComp;
       while(parent.getParent() != null)
          parent = parent.getParent();
 
+      // Get the managed object
+      ManagedObject managedObject = serverComp.getDeployment().getManagedObject(parent.getName());
+      if(managedObject != null)
+      {
+         AttachmentMetaData attachment = new AttachmentMetaData();
+         attachment.setName(managedObject.getAttachmentName());
+         attachment.setAttachment(managedObject.getAttachment());
+         
+         // 
+         RepositoryAttachmentMetaDataFactory.addAttachment(childMetaData, attachment);
+      }
+      else
+      {
+         // maybe throw an exception ?
+         log.debug("No managed object found to update.");
+         return;
+      }
+
+
+      DeploymentContext deployment = ((MainDeployerImpl) mainDeployer).getDeploymentContext(md.getName(), false);
+      StructureMetaData structure = deployment.getDeploymentUnit().getAttachment(StructureMetaData.class);
       
-      ManagedObject o = comp.getDeployment().getManagedObject(parent.getName());
-      if(o != null)
+      // FIXME this should not be done here
+      // apply structure information
+      List<String> processedContexts = new ArrayList<String>();
+      if(structure != null)
       {
-         attachments.put(o.getAttachmentName(), o.getAttachment());
+         // root context
+         RepositoryAttachmentMetaDataFactory.applyStructureContext(parentMetaData, structure.getContext(""));
+         processedContexts.add("");
+         // children
+         if(parentMetaData.getChildren() != null && ! parentMetaData.getChildren().isEmpty())
+         {
+            for(RepositoryAttachmentMetaData child : parentMetaData.getChildren())
+            {
+               // TODO support more nested elements 
+               ContextInfo info = structure.getContext(child.getDeploymentName());
+               if(info != null) 
+               {
+                  RepositoryAttachmentMetaDataFactory.applyStructureContext(child, info);
+                  processedContexts.add(child.getDeploymentName());
+               }
+            }
+         }
+         // Create a plain child meta data for not covered contexts
+         for(ContextInfo info : structure.getContexts())
+         {
+            if(!processedContexts.contains(info.getPath()))
+            {
+               RepositoryAttachmentMetaData newChild = RepositoryAttachmentMetaDataFactory.createInstance();
+               newChild.setDeploymentName(info.getPath());
+               
+               RepositoryAttachmentMetaDataFactory.applyStructureContext(newChild, info);
+               RepositoryAttachmentMetaDataFactory.addChild(parentMetaData, newChild);
+            }
+         }
       }
-      // else, maybe throw an exception ?
 
+      // update lastModified
+      long lastModified = System.currentTimeMillis();
+      // TODO this updates the parent only - maybe we just need to update the child - if we also check it when restoring
+      parentMetaData.setLastModified(lastModified);
+      
+      // Wrap 
+      Map<String, Object> metaDataAttachment = Collections.singletonMap(RepositoryAttachmentMetaData.class.getName(), (Object) parentMetaData);
+      
       // Update the repository deployment attachments
-      activeProfile.updateDeployment(compDeployment, phase, attachments);
+      activeProfile.updateDeployment(compDeployment, phase, metaDataAttachment);
+      
+      // TODO do we need to rebuild managed view after updating a component ? 
+      this.activeProfileLastModified = lastModified;
    }
 
    /**

Modified: trunk/system/.classpath
===================================================================
--- trunk/system/.classpath	2008-10-24 17:02:50 UTC (rev 80057)
+++ trunk/system/.classpath	2008-10-24 17:03:53 UTC (rev 80058)
@@ -24,5 +24,7 @@
 	<classpathentry kind="lib" path="/thirdparty/junit/lib/junit.jar"/>
 	<classpathentry kind="lib" path="/thirdparty/jboss/test/lib/jboss-test.jar"/>
 	<classpathentry kind="lib" path="/thirdparty/jboss/aop/lib/jboss-aop.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/sun-jaxb/lib/jaxb-api.jar" sourcepath="/thirdparty/sun-jaxb/lib/jaxb-api-sources.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/stax-api/lib/stax-api.jar"/>
 	<classpathentry kind="output" path="output/eclipse-classes"/>
 </classpath>

Modified: trunk/system/build.xml
===================================================================
--- trunk/system/build.xml	2008-10-24 17:02:50 UTC (rev 80057)
+++ trunk/system/build.xml	2008-10-24 17:03:53 UTC (rev 80058)
@@ -83,6 +83,9 @@
       <path refid="jboss.common.logging.spi.classpath"/>
       <!-- TEMP for the temporary AOP Deployer -->
       <path refid="javassist.javassist.classpath"/>
+    	<!-- jaxb for attachment serialization -->
+        <path refid="javax.xml.bind.classpath"/>
+        <path refid="javax.xml.stream.classpath"/>
     </path>
 
     &modules;

Added: trunk/system/src/main/org/jboss/system/server/profileservice/attachments/AttachmentMetaData.java
===================================================================
--- trunk/system/src/main/org/jboss/system/server/profileservice/attachments/AttachmentMetaData.java	                        (rev 0)
+++ trunk/system/src/main/org/jboss/system/server/profileservice/attachments/AttachmentMetaData.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.system.server.profileservice.attachments;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+/**
+ * @author <a href="mailto:emuckenh at redhat.com">Emanuel Muckenhuber</a>
+ * @version $Revision$
+ */
+public class AttachmentMetaData
+{
+
+   /** The attachment name */
+   private String name;
+   
+   /** The attachment */
+   private transient Object attachment;
+
+   @XmlElement(name = "attachment-name")
+   public String getName()
+   {
+      return name;
+   }
+
+   public void setName(String name)
+   {
+      this.name = name;
+   }
+
+   @XmlTransient
+   public Object getAttachment()
+   {
+      return attachment;
+   }
+
+   public void setAttachment(Object attachment)
+   {
+      this.attachment = attachment;
+   }
+}
+

Added: trunk/system/src/main/org/jboss/system/server/profileservice/attachments/DeploymentClassPathMetaData.java
===================================================================
--- trunk/system/src/main/org/jboss/system/server/profileservice/attachments/DeploymentClassPathMetaData.java	                        (rev 0)
+++ trunk/system/src/main/org/jboss/system/server/profileservice/attachments/DeploymentClassPathMetaData.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.system.server.profileservice.attachments;
+
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @author <a href="mailto:emuckenh at redhat.com">Emanuel Muckenhuber</a>
+ * @version $Revision$
+ */
+public class DeploymentClassPathMetaData 
+{
+
+   /** The path */
+   private String path;
+   
+   /** The suffixes */
+   private String suffixes;
+   
+   public DeploymentClassPathMetaData()
+   {
+      //
+   }
+   
+   public DeploymentClassPathMetaData(String path, String suffixes)
+   {
+      this.path = path;
+      this.suffixes = suffixes;
+   }
+   
+   @XmlElement(name = "path")
+   public String getPath()
+   {
+      return path;
+   }
+   
+   public void setPath(String path)
+   {
+      this.path = path;
+   }
+   
+   @XmlElement(name = "suffixes")
+   public String getSuffixes()
+   {
+      return suffixes;
+   }
+   
+   public void setSuffixes(String suffixes)
+   {
+      this.suffixes = suffixes;
+   }
+
+}

Added: trunk/system/src/main/org/jboss/system/server/profileservice/attachments/DeploymentStructureMetaData.java
===================================================================
--- trunk/system/src/main/org/jboss/system/server/profileservice/attachments/DeploymentStructureMetaData.java	                        (rev 0)
+++ trunk/system/src/main/org/jboss/system/server/profileservice/attachments/DeploymentStructureMetaData.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -0,0 +1,108 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.system.server.profileservice.attachments;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Basic xml representation helper class of the StructureMetaData.
+ * 
+ * @author <a href="mailto:emuckenh at redhat.com">Emanuel Muckenhuber</a>
+ * @version $Revision$
+ */
+public class DeploymentStructureMetaData
+{
+
+   /** The meta data path */
+   private List<String> metaDataPaths;
+   
+   /** The class paths */
+   private List<DeploymentClassPathMetaData> classPaths;
+   
+   /** The comparator class name */
+   private String comparatorClass;
+   
+   /** The modifcation type */
+   private String modificationType;
+   
+   /** The relative order */
+   private int relatativeOrder;
+ 
+   
+   @XmlElement(name = "meta-data-path")
+   public List<String> getMetaDataPaths()
+   {
+      return metaDataPaths;
+   }
+   
+   public void setMetaDataPaths(List<String> metaDataPaths)
+   {
+      this.metaDataPaths = metaDataPaths;
+   }
+   
+   @XmlElement(name = "class-path")
+   public List<DeploymentClassPathMetaData> getClassPaths()
+   {
+      return classPaths;
+   }
+   
+   public void setClassPaths(List<DeploymentClassPathMetaData> classPaths)
+   {
+      this.classPaths = classPaths;
+   }
+
+   @XmlElement(name = "comparator-class")
+   public String getComparatorClass()
+   {
+      return comparatorClass;
+   }
+   
+   public void setComparatorClass(String comparatorClass)
+   {
+      this.comparatorClass = comparatorClass;
+   }
+   
+   @XmlElement(name = "relative-order")
+   public int getRelatativeOrder()
+   {
+      return relatativeOrder;
+   }
+   
+   public void setRelatativeOrder(int relatativeOrder)
+   {
+      this.relatativeOrder = relatativeOrder;
+   }
+   
+   @XmlElement(name = "modifcation-type")
+   public String getModificationType()
+   {
+      return modificationType;
+   }
+   
+   public void setModificationType(String modificationType)
+   {
+      this.modificationType = modificationType;
+   }
+
+}

Added: trunk/system/src/main/org/jboss/system/server/profileservice/attachments/JAXBAttachmentHelper.java
===================================================================
--- trunk/system/src/main/org/jboss/system/server/profileservice/attachments/JAXBAttachmentHelper.java	                        (rev 0)
+++ trunk/system/src/main/org/jboss/system/server/profileservice/attachments/JAXBAttachmentHelper.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -0,0 +1,107 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.system.server.profileservice.attachments;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.jboss.logging.Logger;
+
+/**
+ * Use JAXB to load and save metadata to the file system.
+ * 
+ * @author <a href="mailto:emuckenh at redhat.com">Emanuel Muckenhuber</a>
+ * @version $Revision$
+ */
+public class JAXBAttachmentHelper
+{
+
+   /** The deployment pre-processed attachments store dir */
+   private final File attachmentsStoreDir;
+   
+   /** The logger */
+   private static final Logger log = Logger.getLogger(JAXBAttachmentHelper.class);
+   
+   public JAXBAttachmentHelper(File attachmentsStoreDir)
+   {
+      this.attachmentsStoreDir = attachmentsStoreDir;
+   }
+
+   protected <T> T loadAttachment(File attachmentsStore, Class<T> expected) throws Exception
+   {
+      JAXBContext ctx = JAXBContext.newInstance(expected);
+      Unmarshaller unmarshaller = ctx.createUnmarshaller();
+      return (T) unmarshaller.unmarshal(attachmentsStore);
+   }
+
+   protected void saveAttachment(File attachmentsStore, Object attachment) throws Exception
+   {
+      JAXBContext ctx = JAXBContext.newInstance(attachment.getClass());
+      Marshaller marshaller = ctx.createMarshaller();
+      marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE);
+      marshaller.marshal(attachment, attachmentsStore);
+   }
+   
+   public <T> T loadAttachment(String baseName, Class<T> expected) throws Exception
+   {
+      if( attachmentsStoreDir == null )
+         throw new IllegalStateException("attachmentsStoreDir has not been set");
+
+      String vfsPath = baseName;
+      vfsPath += ".attachment";
+
+      File attachmentsStore = new File(attachmentsStoreDir, vfsPath);
+      if( attachmentsStore.exists() == false )
+      {
+         log.trace("attachmentStore does not exist: " + attachmentsStore);
+         return null;
+      }
+
+      return loadAttachment(attachmentsStore, expected);
+   }
+
+   public void saveAttachment(String baseName, Object attachment) throws Exception
+   {
+      if( attachmentsStoreDir == null )
+         throw new IllegalStateException("attachmentsStoreDir has not been set");
+
+      String vfsPath = baseName;
+      vfsPath += ".attachment";
+      File attachmentsStore = new File(attachmentsStoreDir, vfsPath);
+      File attachmentsParent = attachmentsStore.getParentFile();
+      if( attachmentsParent.exists() == false )
+      {
+         if( attachmentsParent.mkdirs() == false )
+            throw new IOException("Failed to create attachmentsParent: "+attachmentsParent.getAbsolutePath());
+      }
+
+      if( attachment != null )
+      {
+         saveAttachment(attachmentsStore, attachment);
+      }
+   }
+}
+

Added: trunk/system/src/main/org/jboss/system/server/profileservice/attachments/LazyPredeterminedManagedObjects.java
===================================================================
--- trunk/system/src/main/org/jboss/system/server/profileservice/attachments/LazyPredeterminedManagedObjects.java	                        (rev 0)
+++ trunk/system/src/main/org/jboss/system/server/profileservice/attachments/LazyPredeterminedManagedObjects.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -0,0 +1,212 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.system.server.profileservice.attachments;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Map;
+
+import org.jboss.deployers.spi.attachments.AttachmentsFactory;
+import org.jboss.deployers.spi.attachments.MutableAttachments;
+import org.jboss.profileservice.spi.AttachmentsSerializer;
+
+/**
+ * Basic wrapper for MutableAttachmets. This maintains a list of associated
+ * metadata, which can be loaded lazily and delegates the attachments to AttachmentsImpl.
+ * 
+ * TODO this should use a AttachmentSerializer which stores the meta data
+ * as XML files.  
+ * 
+ * @author <a href="mailto:emuckenh at redhat.com">Emanuel Muckenhuber</a>
+ * @version $Revision$
+ */
+public class LazyPredeterminedManagedObjects implements MutableAttachments
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 1L;
+
+   /** The attachments */
+   private final MutableAttachments delegate;
+   
+   /** The attachmentsSerializer */
+   private final AttachmentsSerializer serializer;
+   
+   /** The relative path */
+   private final String relativePath;
+   
+   /** The available attachments */
+   private final Collection<String> attachments;
+   
+   public LazyPredeterminedManagedObjects(AttachmentsSerializer serializer, String relativePath, Collection<String> attachments)
+   {
+      if(serializer == null)
+         throw new IllegalArgumentException("serializer may not be null;");
+      if(relativePath == null)
+         throw new IllegalArgumentException("relativePath may not be null;");
+      if(attachments == null)
+         throw new IllegalArgumentException("serializer may not be null;");
+      
+      // Create a mutable attachment
+      this.delegate = AttachmentsFactory.createMutableAttachments();
+      // The serializer
+      this.serializer = serializer;
+      // Fix the path, if needed
+      this.relativePath = relativePath.endsWith(File.separator) ? relativePath : relativePath + File.separator;  
+      // The attachments, which can be loaded
+      this.attachments = attachments;
+      
+   }
+
+   public Object addAttachment(String name, Object attachment)
+   {
+      return delegate.addAttachment(name, attachment);
+   }
+
+   public <T> T addAttachment(Class<T> type, T attachment)
+   {
+      return delegate.addAttachment(type, attachment);
+   }
+
+   public <T> T addAttachment(String name, T attachment, Class<T> expectedType)
+   {
+      return delegate.addAttachment(name, attachment, expectedType);
+   }
+
+   public void clear()
+   {
+      delegate.clear();
+   }
+
+   public void clearChangeCount()
+   {
+      delegate.clearChangeCount();
+   }
+
+   public int getChangeCount()
+   {
+      return delegate.getChangeCount();
+   }
+
+   public Object removeAttachment(String name)
+   {
+      return delegate.removeAttachment(name);
+   }
+
+   public <T> T removeAttachment(Class<T> type)
+   {
+      return delegate.removeAttachment(type);
+   }
+
+   public <T> T removeAttachment(String name, Class<T> expectedType)
+   {
+      return delegate.removeAttachment(name, expectedType);
+   }
+
+   public void setAttachments(Map<String, Object> map)
+   {
+      delegate.setAttachments(map);
+   }
+
+   public Object getAttachment(String name)
+   {
+      Object o = delegate.getAttachment(name);
+      if(o == null) o = loadAttachment(name);
+      return o; 
+   }
+
+   public <T> T getAttachment(Class<T> type)
+   {
+      T o = delegate.getAttachment(type); 
+      if(o == null) o = (T) loadAttachment(type.getName());
+      return o;  
+   }
+
+   public <T> T getAttachment(String name, Class<T> expectedType)
+   {
+      T o = delegate.getAttachment(name, expectedType);
+      if(o == null) o = (T) loadAttachment(name);
+      return o;
+   }
+
+   public Map<String, Object> getAttachments()
+   {
+      // TODO - load all attachments ? 
+      return delegate.getAttachments();
+   }
+
+   public boolean hasAttachments()
+   {
+      if(! this.attachments.isEmpty()) return true;
+      return delegate.hasAttachments();
+   }
+
+   public boolean isAttachmentPresent(String name)
+   {
+      if(ishandleAttachment(name)) return true;
+      return delegate.isAttachmentPresent(name);
+   }
+
+   public boolean isAttachmentPresent(Class<?> type)
+   {
+      if(ishandleAttachment(type.getName())) return true;
+      return delegate.isAttachmentPresent(type);
+   }
+
+   public boolean isAttachmentPresent(String name, Class<?> expectedType)
+   {
+      if(ishandleAttachment(name)) return true;
+      return delegate.isAttachmentPresent(name, expectedType);
+   }
+   
+   private boolean ishandleAttachment(String name)
+   {
+      return attachments.contains(name);
+   }
+
+   private Object loadAttachment(String name)
+   {
+      if(! attachments.contains(name))
+         return null;
+      
+      try
+      {
+         // deploy/deployment/child/attachmentName
+         String attachmentName = relativePath + name;
+         // use the con
+         ClassLoader cl = Thread.currentThread().getContextClassLoader();
+         // Load attachment
+         // TODO use different attachment serializer - we actually don't need a Map<String, Object> ?
+         Map<String, Object> map = serializer.loadAttachments(attachmentName, cl);
+         if(map == null)
+            return null;
+         
+         Object o = map.get(name);
+         this.delegate.addAttachment(name, o);
+         return o;
+      }
+      catch(Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+   
+ }

Added: trunk/system/src/main/org/jboss/system/server/profileservice/attachments/RepositoryAttachmentMetaData.java
===================================================================
--- trunk/system/src/main/org/jboss/system/server/profileservice/attachments/RepositoryAttachmentMetaData.java	                        (rev 0)
+++ trunk/system/src/main/org/jboss/system/server/profileservice/attachments/RepositoryAttachmentMetaData.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -0,0 +1,110 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.system.server.profileservice.attachments;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Metadata describing the persisted deployment attachments.
+ * 
+ * @author <a href="mailto:emuckenh at redhat.com">Emanuel Muckenhuber</a>
+ * @version $Revision$
+ */
+ at XmlRootElement(name = "attachments-metadata")
+public class RepositoryAttachmentMetaData
+{
+
+   /** The deployment */
+   private String deploymentName;
+   
+   /** The last update timestamp */
+   private long lastModified;
+   
+   /** The children */
+   private List<RepositoryAttachmentMetaData> children;
+   
+   /** The attachments */
+   private List<AttachmentMetaData> attachments;
+   
+   /** The deployment structure */
+   private DeploymentStructureMetaData deploymentStructure;
+
+   @XmlElement(name = "deployment-name")
+   public String getDeploymentName()
+   {
+      return deploymentName;
+   }
+
+   public void setDeploymentName(String deploymentName)
+   {
+      this.deploymentName = deploymentName;
+   }
+   
+   @XmlElement(name = "last-modified")
+   public long getLastModified()
+   {
+      return lastModified;
+   }
+   
+   public void setLastModified(long lastModified)
+   {
+      this.lastModified = lastModified;
+   }
+   
+   @XmlElement(name = "deployment-structure")
+   public DeploymentStructureMetaData getDeploymentStructure()
+   {
+      return deploymentStructure;
+   }
+   
+   public void setDeploymentStructure(DeploymentStructureMetaData deploymentStructure)
+   {
+      this.deploymentStructure = deploymentStructure;
+   }
+
+   @XmlElement(name = "child")
+   public List<RepositoryAttachmentMetaData> getChildren()
+   {
+      return children;
+   }
+
+   public void setChildren(List<RepositoryAttachmentMetaData> children)
+   {
+      this.children = children;
+   }
+
+   @XmlElement(name = "attachment")
+   public List<AttachmentMetaData> getAttachments()
+   {
+      return attachments;
+   }
+
+   public void setAttachments(List<AttachmentMetaData> attachments)
+   {
+      this.attachments = attachments;
+   }
+
+}
+

Added: trunk/system/src/main/org/jboss/system/server/profileservice/attachments/RepositoryAttachmentMetaDataFactory.java
===================================================================
--- trunk/system/src/main/org/jboss/system/server/profileservice/attachments/RepositoryAttachmentMetaDataFactory.java	                        (rev 0)
+++ trunk/system/src/main/org/jboss/system/server/profileservice/attachments/RepositoryAttachmentMetaDataFactory.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -0,0 +1,123 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.system.server.profileservice.attachments;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.deployers.spi.structure.ClassPathEntry;
+import org.jboss.deployers.spi.structure.ContextInfo;
+import org.jboss.managed.api.ManagedDeployment;
+
+/**
+ * Common RepositoryAttachmentMetaData operations.
+ * 
+ * @author <a href="mailto:emuckenh at redhat.com">Emanuel Muckenhuber</a>
+ * @version $Revision$
+ */
+public class RepositoryAttachmentMetaDataFactory
+{
+
+   public static RepositoryAttachmentMetaData createInstance()
+   {
+      return new RepositoryAttachmentMetaData();
+   }
+   
+   public static RepositoryAttachmentMetaData createInstance(ManagedDeployment md)
+   {
+      if(md == null)
+         throw new IllegalArgumentException("managed deployment may not be null.");
+      
+      RepositoryAttachmentMetaData metaData = createInstance();
+      metaData.setDeploymentName(md.getSimpleName());
+      return metaData;
+   }
+   
+   public static RepositoryAttachmentMetaData createNewParent(ManagedDeployment md, RepositoryAttachmentMetaData child)
+   {
+      if(md == null)
+         throw new IllegalArgumentException("managed deployment may not be null.");
+      
+      RepositoryAttachmentMetaData metaData = createInstance(md);
+      addChild(metaData, child);
+      return metaData;
+   }
+   
+   public static void addChild(RepositoryAttachmentMetaData parent, RepositoryAttachmentMetaData child)
+   {
+      if(parent == null)
+         throw new IllegalArgumentException("parent may not be null.");
+      
+      if(parent.getChildren() == null)
+         parent.setChildren(new ArrayList<RepositoryAttachmentMetaData>());
+      
+      parent.getChildren().add(child);
+   }
+   
+   public static void addAttachment(RepositoryAttachmentMetaData metaData, AttachmentMetaData attachment)
+   {
+      if(metaData == null)
+         throw new IllegalArgumentException("meta data may not be null.");
+      
+      if(metaData.getAttachments() == null)
+         metaData.setAttachments(new ArrayList<AttachmentMetaData>());
+      
+      metaData.getAttachments().add(attachment);
+   }
+   
+   public static void applyStructureContext(RepositoryAttachmentMetaData metaData, ContextInfo info)
+   {
+      if(metaData == null)
+         throw new IllegalArgumentException("meta data may not be null.");
+      if(info == null)
+         throw new IllegalArgumentException("context info may not be null.");
+      
+      DeploymentStructureMetaData structure = new DeploymentStructureMetaData(); 
+      
+      // meta data paths
+      structure.setMetaDataPaths(info.getMetaDataPath());
+      // classpath
+      structure.setClassPaths(getDeploymentClassPathMetaData(info));
+      // comparator
+      structure.setComparatorClass(info.getComparatorClassName());
+      // relativeOrder
+      structure.setRelatativeOrder(info.getRelativeOrder());
+      
+      metaData.setDeploymentStructure(structure);
+   }
+   
+   protected static List<DeploymentClassPathMetaData> getDeploymentClassPathMetaData(ContextInfo info)
+   {
+      if(info == null)
+         throw new IllegalArgumentException("context info may not be null.");
+      
+      if(info.getClassPath() == null || info.getClassPath().isEmpty())
+         return null;
+      
+      List<DeploymentClassPathMetaData> classPath = new ArrayList<DeploymentClassPathMetaData>();
+      for(ClassPathEntry entry : info.getClassPath())
+         classPath.add(new DeploymentClassPathMetaData(entry.getPath(), entry.getSuffixes()));
+      
+      return classPath;
+   }
+}
+

Modified: trunk/system/src/main/org/jboss/system/server/profileservice/repository/SerializableDeploymentRepository.java
===================================================================
--- trunk/system/src/main/org/jboss/system/server/profileservice/repository/SerializableDeploymentRepository.java	2008-10-24 17:02:50 UTC (rev 80057)
+++ trunk/system/src/main/org/jboss/system/server/profileservice/repository/SerializableDeploymentRepository.java	2008-10-24 17:03:53 UTC (rev 80058)
@@ -26,7 +26,6 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.ObjectOutputStream;
 import java.io.SyncFailedException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -45,6 +44,9 @@
 import java.util.zip.ZipInputStream;
 
 import org.jboss.deployers.spi.attachments.Attachments;
+import org.jboss.deployers.spi.attachments.MutableAttachments;
+import org.jboss.deployers.spi.structure.ClassPathEntry;
+import org.jboss.deployers.spi.structure.ContextInfo;
 import org.jboss.deployers.vfs.spi.client.VFSDeployment;
 import org.jboss.deployers.vfs.spi.client.VFSDeploymentFactory;
 import org.jboss.logging.Logger;
@@ -57,6 +59,12 @@
 import org.jboss.profileservice.spi.NoSuchProfileException;
 import org.jboss.profileservice.spi.ProfileKey;
 import org.jboss.profileservice.spi.ModificationInfo.ModifyStatus;
+import org.jboss.system.server.profileservice.attachments.AttachmentMetaData;
+import org.jboss.system.server.profileservice.attachments.DeploymentClassPathMetaData;
+import org.jboss.system.server.profileservice.attachments.DeploymentStructureMetaData;
+import org.jboss.system.server.profileservice.attachments.JAXBAttachmentHelper;
+import org.jboss.system.server.profileservice.attachments.LazyPredeterminedManagedObjects;
+import org.jboss.system.server.profileservice.attachments.RepositoryAttachmentMetaData;
 import org.jboss.util.file.Files;
 import org.jboss.virtual.VFS;
 import org.jboss.virtual.VirtualFile;
@@ -110,6 +118,14 @@
    private ReentrantReadWriteLock contentLock = new ReentrantReadWriteLock(true);
    /** Should an attempt to overwrite existing content fail in {@link #addDeploymentContent(String, ZipInputStream, DeploymentPhase)}*/
    private boolean failIfAlreadyExists = false;
+   /** The deployment factory */
+   private VFSDeploymentFactory factory = VFSDeploymentFactory.getInstance();
+   
+   /** 
+    * A helper for xml serialization
+    * TODO this should be removed. 
+    */
+   private JAXBAttachmentHelper xmlSerializer;
 
    public SerializableDeploymentRepository(File root, URI[] appURIs, ProfileKey key)
    {
@@ -236,6 +252,8 @@
          if(contentRoot == null)
             throw new FileNotFoundException("Failed to obtain content dir for phase: "+phase);
          File contentFile = new File(contentRoot, name);
+         // TODO do we need to create the parent directory if the name is myDeployments/myRealDeployment.jar ?
+         
          if(failIfAlreadyExists && contentFile.exists())
             throw new SyncFailedException("Deployment content already exists: "+contentFile.getAbsolutePath());
          FileOutputStream fos = new FileOutputStream(contentFile);
@@ -414,17 +432,6 @@
       lastModified = System.currentTimeMillis();
    }
 
-   // TODO
-   public void updateDeployment(VFSDeployment d, DeploymentPhase phase,
-         Map<String, Object> attachments)
-      throws Exception
-   {
-      String baseName = d.getSimpleName();
-      if(baseName.length() == 0)
-         baseName = d.getName();
-      serializer.saveAttachments(baseName, attachments);
-   }
-
    public VFSDeployment getDeployment(String name, DeploymentPhase phase)
       throws Exception, NoSuchDeploymentException
    {
@@ -529,14 +536,14 @@
                      log.trace(name + " was removed");
                }
                // Check for modification
-               else if( root.hasBeenModified() || 
+               else if( hasBeenModified(root) || 
                      hasDeploymentContentFlags(root.getPathName(), DeploymentPhase.APPLICATION, DeploymentContentFlags.MODIFIED) )
                {
                   long rootLastModified = root.getLastModified();
                   if( trace )
                      log.trace(name + " was modified: " + rootLastModified);
                   // Need to create a duplicate ctx
-                  VFSDeployment ctx2 = loadDeploymentData(root);
+                  VFSDeployment ctx2 = loadDeploymentData(root, DeploymentPhase.APPLICATION);
                   ModificationInfo info = new ModificationInfo(ctx2, rootLastModified, ModifyStatus.MODIFIED);
                   modified.add(info);
                }
@@ -556,7 +563,7 @@
                         log.trace("Ignoring locked application: "+ vf);
                      continue;
                   }
-                  VFSDeployment ctx = loadDeploymentData(vf);
+                  VFSDeployment ctx = loadDeploymentData(vf, DeploymentPhase.APPLICATION);
                   ModificationInfo info = new ModificationInfo(ctx, vf.getLastModified(), ModifyStatus.ADDED);
                   modified.add(info);
                   applicationCtxs.put(ctx.getName(), ctx);
@@ -575,6 +582,18 @@
          lastModified = System.currentTimeMillis();
       return modified;
    }
+   
+   /**
+    * Has the root been modified.
+    *
+    * @param root the virtual file root
+    * @return true if modifed
+    * @throws Exception for any error
+    */
+   protected boolean hasBeenModified(VirtualFile root) throws Exception
+   {
+      return root.hasBeenModified();
+   }
 
    public Collection<VFSDeployment> getDeployments(DeploymentPhase phase)
       throws Exception
@@ -615,6 +634,7 @@
          lastModified = System.currentTimeMillis();
       return ctx;
    }
+   
    public String toString()
    {
       StringBuilder tmp = new StringBuilder(super.toString());
@@ -700,8 +720,9 @@
       }
 
       adminEditsRoot = new File(profileRoot, "attachments");
+      // TODO the xmlSerializer should be removed
+      this.xmlSerializer = new JAXBAttachmentHelper(adminEditsRoot);
 
-      // TODO: need to load pre-determined attachments using serializer
       if( bootstrapDir != null )
       {
          VFS bootstrapVFS = VFS.getVFS(bootstrapDir.toURI());
@@ -780,24 +801,26 @@
    public void addManagedObject(String vfsPath, Attachments edits)
       throws IOException
    {
-      Map<String, Object> map = edits.getAttachments();
-      File attachments = new File(adminEditsRoot, vfsPath+".edits");
-      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(attachments));
-      try
-      {
-         oos.writeObject(map);
-      }
-      finally
-      {
-         try
-         {
-            oos.close();
-         }
-         catch (IOException ignore)
-         {
-         }
-      }
-      lastModified = System.currentTimeMillis();
+      // TODO what should this do ?
+      throw new UnsupportedOperationException("addManagedObject");
+//      Map<String, Object> map = edits.getAttachments();
+//      File attachments = new File(adminEditsRoot, vfsPath+".edits");
+//      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(attachments));
+//      try
+//      {
+//         oos.writeObject(map);
+//      }
+//      finally
+//      {
+//         try
+//         {
+//            oos.close();
+//         }
+//         catch (IOException ignore)
+//         {
+//         }
+//      }
+//      lastModified = System.currentTimeMillis();
    }
 
    protected void addDeployer(String vfsPath, VFSDeployment ctx)
@@ -808,9 +831,6 @@
 
    protected void addApplication(String vfsPath, VFSDeployment ctx) throws Exception
    {
-      if(vfsPath.startsWith("test"))
-         log.error("Should not see a test... key");
-
       log.info("Adding application: " + vfsPath + " / " + ctx);
       this.applicationCtxs.put(vfsPath, ctx);
    }
@@ -879,17 +899,21 @@
 
    protected VFSDeployment getApplication(String vfsPath) throws Exception
    {
+      boolean trace = log.isTraceEnabled();
       VFSDeployment ctx = applicationCtxs.get(vfsPath);
       if( ctx == null )
       {
          // Try to find the simple name
-         log.info("Failed to find application for: "+vfsPath+", scanning for simple name");
+         if(trace)
+            log.trace("Failed to find application for: "+vfsPath+", scanning for simple name");
          for(VFSDeployment deployment : applicationCtxs.values())
          {
-            log.debug("Checking: "+deployment.getSimpleName());
+            if(trace)
+               log.trace("Checking: "+deployment.getSimpleName());
             if(deployment.getSimpleName().equals(vfsPath))
             {
-               log.debug("Matched to simple name of deployment:"+deployment);
+               if(trace)
+                  log.trace("Matched to simple name of deployment:"+deployment);
                ctx = deployment;
                break;
             }
@@ -962,7 +986,7 @@
          List<VirtualFile> children = bootstrapDir.getChildren();
          for(VirtualFile vf : children)
          {
-            VFSDeployment vfCtx = loadDeploymentData(vf);
+            VFSDeployment vfCtx = loadDeploymentData(vf, DeploymentPhase.BOOTSTRAP);
             bootstrapCtxs.put(vfCtx.getName(), vfCtx);       
          }
       }
@@ -975,7 +999,7 @@
          VirtualFile jbossServiceVF = confVF.getChild("jboss-service.xml");
          if(jbossServiceVF == null)
             throw new FileNotFoundException("Failed to find jboss-service.xml under conf");
-         VFSDeployment vfCtx = loadDeploymentData(jbossServiceVF);
+         VFSDeployment vfCtx = loadDeploymentData(jbossServiceVF, DeploymentPhase.BOOTSTRAP);
          bootstrapCtxs.put(vfCtx.getName(), vfCtx);                
       }
    }
@@ -992,7 +1016,7 @@
       List<VirtualFile> children = deployersDir.getChildren();
       for(VirtualFile vf : children)
       {
-         VFSDeployment vfCtx = loadDeploymentData(vf);
+         VFSDeployment vfCtx = loadDeploymentData(vf, DeploymentPhase.DEPLOYER);
          deployerCtxs.put(vfCtx.getName(), vfCtx);       
       }
    }
@@ -1010,7 +1034,7 @@
       addedDeployments(added, applicationDir);
       for (VirtualFile vf : added)
       {
-         VFSDeployment vfCtx = loadDeploymentData(vf);
+         VFSDeployment vfCtx = loadDeploymentData(vf, DeploymentPhase.APPLICATION);
          applicationCtxs.put(vfCtx.getName(), vfCtx);
       }
    }
@@ -1050,17 +1074,282 @@
    }
 
    /**
-    * TODO: this could be dropped since the serialize aspect loads the data
+    * TODO Map<String, Object should not be required ?
+    */
+   public void updateDeployment(VFSDeployment d, DeploymentPhase phase,
+         Map<String, Object> attachments) throws Exception
+   {
+      RepositoryAttachmentMetaData metaData = (RepositoryAttachmentMetaData) attachments.get(RepositoryAttachmentMetaData.class.getName());
+      if(metaData != null)
+      {
+         this.updateDeployment(d, phase, metaData);
+      }
+      else
+      {
+         log.error("no metadata attached.");
+      }
+   }
+   
+   /**
+    * Update a deployment based on it's RepositoryAttachmentMetaData
+    * 
+    * TODO use a xml serializer, to drop the use of the childAttachment maps. 
+    * 
+    * @param d
+    * @param phase
+    * @param metaData
+    * @throws Exception
+    */
+   public void updateDeployment(VFSDeployment d, DeploymentPhase phase,
+         RepositoryAttachmentMetaData metaData)
+      throws Exception
+   {
+      boolean trace = log.isTraceEnabled();
+      
+      // The PhaseDir
+      File path = getPhaseDir(phase);
+      if(path == null)
+      {
+         log.warn("Could not get PhaseDir for DeploymentPhase: " + phase + ", unable to perstisted attachments.");
+         return;
+      }
+      
+      // attachments/deploy/deployment/
+      String deploymentPath = path.getName() + File.separator + d.getSimpleName() + File.separator;
+      RepositoryAttachmentMetaData savedMetaData = loadAttachmentMetaData(deploymentPath); 
+      
+      if(savedMetaData != null)
+      {
+         if(trace)
+            log.trace("Previous metadata found for deployment: " + d);
+         // TODO merge updates 
+      }
+         
+      // Save attachments for the root context
+      if(metaData.getAttachments() != null && !metaData.getAttachments().isEmpty())
+      {
+         for(AttachmentMetaData attachment : metaData.getAttachments())
+         {
+            String attachmentPath = deploymentPath + attachment.getName();
+            // TODO 
+            Map<String, Object> childAttachment = new HashMap<String, Object>();
+            childAttachment.put(attachment.getName(), attachment.getAttachment());
+            // Serialize the attachment
+            serializer.saveAttachments(attachmentPath, childAttachment);
+            
+            if(trace)
+               log.trace("Stored attachment to : " + attachmentPath);
+         }
+      }
+      
+      // Save attachments for the children
+      List<RepositoryAttachmentMetaData> children = metaData.getChildren();
+      if(children != null && !children.isEmpty())
+      {
+         for(RepositoryAttachmentMetaData child : children)
+         {
+            // The relative child path 
+            String childPath = deploymentPath + child.getDeploymentName() + File.separator;
+            if(child.getAttachments() != null && ! child.getAttachments().isEmpty())
+            {
+               for(AttachmentMetaData attachment : child.getAttachments())
+               {
+                  String attachmentPath = childPath + attachment.getName();
+                  // TODO 
+                  Map<String, Object> childAttachment = new HashMap<String, Object>();
+                  childAttachment.put(attachment.getName(), attachment.getAttachment());
+                  // Serialize the attachment
+                  serializer.saveAttachments(attachmentPath, childAttachment);
+                  
+                  if(trace)
+                     log.trace("Stored attachment to : " + attachmentPath);
+               }
+            }
+         }
+      }
+      
+      // Store the repository metadata
+      xmlSerializer.saveAttachment(deploymentPath + "metadata", metaData);
+   }
+   
+   /**
+    * Load the attachment metadata.
+    * 
     * @param file
     * @return the deployment
     */
-   private VFSDeployment loadDeploymentData(VirtualFile file)
+   private VFSDeployment loadDeploymentData(VirtualFile file, DeploymentPhase phase)
    {
-      // Check for a persisted context
-      // Load the base deployment
-      VFSDeployment deployment = VFSDeploymentFactory.getInstance().createVFSDeployment(file);
-      log.debug("Created deployment: "+deployment);
+      boolean trace = log.isTraceEnabled(); 
+      // Create VFS deployment
+      VFSDeployment deployment = factory.createVFSDeployment(file);
+      if(trace)
+         log.trace("Created deployment: " + deployment);
+      
+      // The PhaseDir
+      File path = getPhaseDir(phase);
+      if(path == null)
+      {
+         log.debug("Could not get PhaseDir for DeploymentPhase: " + phase + ", do not scann for perstisted attachments.");
+         return deployment;
+      }
+         
+
+      // attachments/deploy/deployment/
+      String deploymentPath = path.getName() + File.separator + deployment.getSimpleName() + File.separator;
+      if(trace)
+         log.trace("trying to load attachment from relative path: " + deploymentPath);
+      
+      // Load the metadata
+      RepositoryAttachmentMetaData attachmentMetaData = loadAttachmentMetaData(deploymentPath);
+      
+      if(attachmentMetaData == null)
+      {
+         if(trace)
+            log.trace("Did not find any presisted metadata for deployment: " + deployment);
+         return deployment;
+      }
+      
+      try
+      {
+         // If the deployment has changes we skip this.
+         // TODO delete attachments ?
+         if(attachmentMetaData.getLastModified() < file.getLastModified())
+         {
+            log.debug("Not using the persisted metadata, as the deployment was modified.");
+            return deployment;
+         }
+      }
+      catch(IOException e)
+      {
+         log.error("failed to get LastModified date for file, no using persisted metadata: "+ file.getPathName());
+         return deployment;
+      }
+      
+      // Start with "" the root contextPath
+      rebuildStructureContext(deployment, "", deploymentPath, attachmentMetaData, trace);
+      
       return deployment;
    }
+   
+   /**
+    * Rebuild the StructureMetaData based on the RepositoryAttachmentMetaData
+    * and add predeterminedManagedObjects.
+    * 
+    * @param deployment the VFSDeployment
+    * @param contextName the structure context path
+    * @param deploymentPath the path to the attachement
+    * @param attachmentMetaData the meta data
+    */
+   protected void rebuildStructureContext(VFSDeployment deployment,
+         String contextName,
+         String deploymentPath,
+         RepositoryAttachmentMetaData attachmentMetaData,
+         boolean trace)
+   {
+      boolean isParent = "".equals(contextName);
+      
+      if(trace)
+         log.trace("Rebuilding StructureMetaData for context: " + contextName);
+      
+      
+      
+      // Get the stored deployment structure
+      DeploymentStructureMetaData structure = attachmentMetaData.getDeploymentStructure();
+      
+      // MetaData and ClassPath
+      List<String> metaDataPaths = new ArrayList<String>();
+      List<ClassPathEntry> classPath = new ArrayList<ClassPathEntry>();
+      if(structure != null)
+      {
+         if(structure.getClassPaths() != null)
+         {
+            for(DeploymentClassPathMetaData md : structure.getClassPaths())
+               classPath.add(factory.createClassPathEntry(md.getPath(), md.getSuffixes()));
+         }
+         
+         if(structure.getMetaDataPaths() != null)
+            metaDataPaths = structure.getMetaDataPaths(); 
+      }
+      
+      // Now create the ContextInfo
+      ContextInfo info = factory.addContext(deployment, contextName, metaDataPaths, classPath);
+      if(structure != null)
+      {
+         // Set the comparator
+         info.setComparatorClassName(structure.getComparatorClass());
+         // Set the relative order
+         info.setRelativeOrder(structure.getRelatativeOrder());
+      }
+      if(trace)
+         log.trace("created ContextInfo: "+  info + " for deployment: "+ deployment);
+      
+      // Add attachments if needed 
+      if(attachmentMetaData.getAttachments() != null && ! attachmentMetaData.getAttachments().isEmpty())
+      {
+         Set<String> availableAttachments = new HashSet<String>();
+         for(AttachmentMetaData attachment : attachmentMetaData.getAttachments())
+            availableAttachments.add(attachment.getName());
 
+          MutableAttachments mutable =  new LazyPredeterminedManagedObjects(this.serializer, deploymentPath, availableAttachments);
+          
+          // TODO is there a better way to do this ?
+          if(isParent)
+             deployment.setPredeterminedManagedObjects(mutable);
+          else 
+             info.setPredeterminedManagedObjects(mutable);
+          
+          if(trace)
+             log.trace("Added PredetminedManagedObjects: " + availableAttachments + " to context " + contextName);
+      }
+      else
+      {
+         if(trace)
+            log.trace("No PredetminedManagedObjects found for context " + contextName);         
+      }
+      
+      // Process children
+      List<RepositoryAttachmentMetaData> children = attachmentMetaData.getChildren(); 
+      if(children != null && ! children.isEmpty())
+      {
+         for(RepositoryAttachmentMetaData childMetaData : children)
+         {
+            // The structure context path
+            String childContextName = contextName + "/" + childMetaData.getDeploymentName();
+            // The relative path of the child attachment (therefore File.separator) 
+            String relativePath = deploymentPath + childMetaData.getDeploymentName() + File.separator;
+            
+            if(trace)
+               log.trace("Processing child context: "+ childContextName);
+            
+            // Rebuild the structure of the child
+            rebuildStructureContext(deployment, childContextName, relativePath, childMetaData, trace);
+         }
+      }
+   }
+   
+   /**
+    * Load the attachment metadata for a deployment.
+    * 
+    * @param relativeDeploymentPath the relatative path to the metadata
+    * @return the attachment metadata
+    */
+   protected RepositoryAttachmentMetaData loadAttachmentMetaData(String relativeDeploymentPath)
+   {
+      final String metaDataName = "metadata";
+      // attachments/deploy/deployment/metadata
+      String fixedMetadataPath = relativeDeploymentPath.endsWith(File.separator) ? relativeDeploymentPath + metaDataName : relativeDeploymentPath + File.separator + metaDataName;   
+               
+      try
+      {
+         // Try to load metadata Attachment
+         return xmlSerializer.loadAttachment(fixedMetadataPath, RepositoryAttachmentMetaData.class);
+      }
+      catch(Exception e)
+      {
+         log.error("Failed to load attachment metadata from relative path: "+ relativeDeploymentPath, e);
+      }
+      return null;
+   }
+
 }




More information about the jboss-cvs-commits mailing list