Permalink
Browse files

[SHRINKWRAP-353] Alternate impl for shallowCopy to centralize copy lo…

…gic; reveals design flaw noted by SHRINKWRAP-362
  • Loading branch information...
1 parent 47dbd4d commit dcf5f87cd94928aa876ff69f3850784b9056e008 @ALRubinger ALRubinger committed Nov 17, 2011
@@ -60,7 +60,7 @@
public abstract class ArchiveBase<T extends Archive<T>> implements Archive<T>, Configurable, ArchiveFormatAssociable {
// -------------------------------------------------------------------------------------||
- // Class Members ----------------------------------------------------------------------||
+ // Class Members -----------------------------------------------------------------------||
// -------------------------------------------------------------------------------------||
/**
@@ -69,7 +69,7 @@
private static final Logger log = Logger.getLogger(ArchiveBase.class.getName());
// -------------------------------------------------------------------------------------||
- // Instance Members -------------------------------------------------------------------||
+ // Instance Members --------------------------------------------------------------------||
// -------------------------------------------------------------------------------------||
/**
@@ -83,7 +83,7 @@
private final Configuration configuration;
// -------------------------------------------------------------------------------------||
- // Constructor ------------------------------------------------------------------------||
+ // Constructor -------------------------------------------------------------------------||
// -------------------------------------------------------------------------------------||
/**
@@ -489,6 +489,51 @@ public T merge(final Archive<?> source, final String path) throws IllegalArgumen
/**
* {@inheritDoc}
*
+ * @see org.jboss.shrinkwrap.api.Archive#shallowCopy()
+ */
+ @Override
+ public final Archive<T> shallowCopy() {
+ // Use existing configuration
+ final Configuration configuration = this.getConfiguration();
+
+ // Create a new archive to which we'll shallow copy all assets
+ final Archive<T> from = this;
+
+ //TODO SHRINKWRAP-362
+ /*
+ * The design of this particular hack is particularly offensive:
+ *
+ * First off, we're binding this abstract parent to use a specific
+ * implementation in creating new instances.
+ *
+ * Second, there's the unchecked casting.
+ *
+ * Mostly, however, is that this "shallowCopy" issue
+ * denoted by SHRINKWRAP-353 calls into question
+ * the whole design of having ArchiveBase implement
+ * the full contract set defined by Archive. Archive is
+ * targeted to be an end-user view; and ArchiveBase is really
+ * a set of operations for the underlying storage mechanism. What
+ * would be much more appropriate is a contract set for Archive, and
+ * a separate contract for the underlying storage (ie. file system).
+ * To be addressed in SHRINKWRAP-362.
+ *
+ */
+ @SuppressWarnings("unchecked")
+ final Archive<T> to = Archive.class.cast(new MemoryMapArchiveImpl(configuration));
+
+ // Now loop through and add all content
+ for (final ArchivePath path : from.getContent().keySet()) {
+ to.add(from.get(path).getAsset(), path);
+ }
+
+ // Return
+ return to;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.shrinkwrap.api.Archive#merge(org.jboss.shrinkwrap.api.Archive, org.jboss.shrinkwrap.api.Path,
* org.jboss.shrinkwrap.api.Filter)
*/
@@ -676,19 +721,14 @@ public Configuration getConfiguration() {
return configuration;
}
- // -------------------------------------------------------------------------------------||
- // Contracts --------------------------------------------------------------------------||
- // -------------------------------------------------------------------------------------||
-
/**
- * Returns the actual typed class for this instance, used in safe casting for covariant return types
- *
+ * Exposes the actual class used in casting
* @return
*/
protected abstract Class<T> getActualClass();
// -------------------------------------------------------------------------------------||
- // Internal Helper Methods ------------------------------------------------------------||
+ // Internal Helper Methods -------------------------------------------------------------||
// -------------------------------------------------------------------------------------||
/**
@@ -51,18 +51,6 @@ public GenericArchiveImpl(final Archive<?> delegate) {
/**
* {@inheritDoc}
*
- * @see Archive#shallowCopy()
- */
- @Override
- public GenericArchiveImpl shallowCopy() {
- GenericArchiveImpl newInstance = new GenericArchiveImpl(getArchive().shallowCopy());
- ShallowCopy.shallowCopyContentTo(this, newInstance);
- return newInstance;
- }
-
- /**
- * {@inheritDoc}
- *
* @see org.jboss.shrinkwrap.impl.base.container.ContainerBase#getClassesPath()
*/
@Override
@@ -66,23 +66,10 @@ public MemoryMapArchiveImpl(final String archiveName, final Configuration config
/**
* {@inheritDoc}
- *
- * @see Archive#shallowCopy()
- */
- @Override
- public MemoryMapArchiveImpl shallowCopy() {
- MemoryMapArchiveImpl newInstance = new MemoryMapArchiveImpl(getConfiguration());
- ShallowCopy.shallowCopyContentTo(this, newInstance);
- return newInstance;
- }
-
- /**
- * {@inheritDoc}
- *
* @see org.jboss.shrinkwrap.impl.base.ArchiveBase#getActualClass()
*/
@Override
- protected Class<MemoryMapArchive> getActualClass() {
+ public Class<MemoryMapArchive> getActualClass() {
return MemoryMapArchive.class;
}
@@ -1,20 +0,0 @@
-package org.jboss.shrinkwrap.impl.base;
-
-import org.jboss.shrinkwrap.api.Archive;
-import org.jboss.shrinkwrap.api.ArchivePath;
-
-public class ShallowCopy {
-
- /**
- * Copies pointers to assets from an archive to another archive. Paths are recreated in the target archive.
- *
- * @param from origin archive
- * @param to target archive
- */
- public static <T extends Archive<T>> void shallowCopyContentTo(Archive<T> from, Archive<T> to) {
- for (ArchivePath path : from.getContent().keySet()) {
- to.add(from.get(path).getAsset(), path);
- }
- }
-
-}
@@ -28,14 +28,18 @@
import java.util.Map;
import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ArchiveFactory;
import org.jboss.shrinkwrap.api.ArchiveFormat;
import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.ClassLoaderSearchUtilDelegator;
+import org.jboss.shrinkwrap.api.Configuration;
+import org.jboss.shrinkwrap.api.Domain;
import org.jboss.shrinkwrap.api.Filter;
import org.jboss.shrinkwrap.api.Filters;
import org.jboss.shrinkwrap.api.IllegalArchivePathException;
import org.jboss.shrinkwrap.api.Node;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.Asset;
import org.jboss.shrinkwrap.api.asset.ByteArrayAsset;
import org.jboss.shrinkwrap.api.asset.ClassAsset;
@@ -490,8 +494,28 @@ public String getName() {
/**
* {@inheritDoc}
- *
- * @see org.jboss.declarchive.api.Archive#toString(boolean)
+ * @see org.jboss.shrinkwrap.api.Archive#shallowCopy()
+ */
+ @Override
+ public Archive<T> shallowCopy() {
+ // Get the actual class type and make a shallow copy of the the underlying archive,
+ // using the same underlying configuration
+ final Class<T> actualClass = this.getActualClass();
+ final Archive<?> underlyingArchive = this.getArchive();
+ final Configuration existingConfig= ((Configurable)underlyingArchive).getConfiguration();
+ final Domain domain = ShrinkWrap.createDomain(existingConfig);
+ final ArchiveFactory factory = domain.getArchiveFactory();
+ final Archive<T> newArchive = factory.create(actualClass, this.getName());
+ final Map<ArchivePath, Node> contents = underlyingArchive.getContent();
+ for (final ArchivePath path : contents.keySet()) {
+ newArchive.add(contents.get(path).getAsset(), path);
+ }
+ return newArchive;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see java.lang.Object#toString()
*/
@Override
public String toString() {
@@ -500,8 +524,7 @@ public String toString() {
/**
* {@inheritDoc}
- *
- * @see org.jboss.declarchive.api.Archive#toString(boolean)
+ * @see org.jboss.shrinkwrap.api.Archive#toString(boolean)
*/
@Override
public String toString(final boolean verbose) {
@@ -518,13 +541,21 @@ public String toString(final Formatter formatter) throws IllegalArgumentExceptio
return this.getArchive().toString(formatter);
}
+ /**
+ * {@inheritDoc}
+ * @see java.lang.Object#hashCode()
+ */
@Override
public int hashCode() {
return this.getArchive().hashCode();
}
+ /**
+ * {@inheritDoc}
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
@Override
- public boolean equals(Object obj) {
+ public boolean equals(final Object obj) {
if (obj instanceof ArchiveBase<?>) {
return this.getArchive().equals(obj);
}
@@ -548,20 +579,18 @@ public boolean equals(Object obj) {
*/
protected abstract ArchivePath getManifestPath();
- /*
- * (non-Javadoc)
- *
- * @see org.jboss.declarchive.api.container.ManifestContainer#setManifest(java.lang.String)
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.api.container.ManifestContainer#setManifest(java.lang.String)
*/
@Override
public final T setManifest(String resourceName) {
Validate.notNull(resourceName, "ResourceName should be specified");
return setManifest(new ClassLoaderAsset(resourceName));
}
- /*
- * (non-Javadoc)
- *
+ /**
+ * {@inheritDoc}
* @see org.jboss.shrinkwrap.api.container.ManifestContainer#setManifest(java.io.File)
*/
@Override
@@ -570,9 +599,8 @@ public T setManifest(File resource) throws IllegalArgumentException {
return setManifest(new FileAsset(resource));
}
- /*
- * (non-Javadoc)
- *
+ /**
+ * {@inheritDoc}
* @see org.jboss.shrinkwrap.api.container.ManifestContainer#setManifest(java.net.URL)
*/
@Override
@@ -581,22 +609,19 @@ public T setManifest(URL resource) throws IllegalArgumentException {
return setManifest(new UrlAsset(resource));
}
- /*
- * (non-Javadoc)
- *
- * @see org.jboss.shrinkwrap.api.container.ManifestContainer#setManifest(org.jboss.shrinkwrap.api.Asset)
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.api.container.ManifestContainer#setManifest(org.jboss.shrinkwrap.api.asset.Asset)
*/
@Override
public T setManifest(Asset resource) throws IllegalArgumentException {
Validate.notNull(resource, "Resource should be specified");
return addAsManifestResource(resource, "MANIFEST.MF");
}
- /*
- * (non-Javadoc)
- *
- * @see org.jboss.shrinkwrap.api.container.ManifestContainer#setManifestResource(java.lang.Package,
- * java.lang.String)
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.api.container.ManifestContainer#setManifest(java.lang.Package, java.lang.String)
*/
@Override
public T setManifest(Package resourcePackage, String resourceName) throws IllegalArgumentException {
@@ -607,32 +632,29 @@ public T setManifest(Package resourcePackage, String resourceName) throws Illega
return setManifest(classloaderResourceName);
}
- /*
- * (non-Javadoc)
- *
- * @see org.jboss.declarchive.api.container.ManifestContainer#addManifestResource(java.lang.String)
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.api.container.ManifestContainer#addAsManifestResource(java.lang.String)
*/
@Override
public final T addAsManifestResource(String resourceName) {
Validate.notNull(resourceName, "ResourceName should be specified");
return addAsManifestResource(fileFromResource(resourceName), resourceName);
}
- /*
- * (non-Javadoc)
- *
- * @see org.jboss.shrinkwrap.api.container.ManifestContainer#addManifestResource(java.io.File)
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.api.container.ManifestContainer#addAsManifestResource(java.io.File)
*/
@Override
public T addAsManifestResource(File resource) throws IllegalArgumentException {
Validate.notNull(resource, "Resource should be specified");
return addAsManifestResource(resource, resource.getName());
}
- /*
- * (non-Javadoc)
- *
- * @see org.jboss.shrinkwrap.api.container.ManifestContainer#addManifestResource(java.lang.String, java.lang.String)
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.api.container.ManifestContainer#addAsManifestResource(java.lang.String, java.lang.String)
*/
@Override
public T addAsManifestResource(String resourceName, String target) throws IllegalArgumentException {
@@ -642,10 +664,9 @@ public T addAsManifestResource(String resourceName, String target) throws Illega
return addAsManifestResource(fileFromResource(resourceName), target);
}
- /*
- * (non-Javadoc)
- *
- * @see org.jboss.shrinkwrap.api.container.ManifestContainer#addManifestResource(java.io.File, java.lang.String)
+ /**
+ * {@inheritDoc}
+ * @see org.jboss.shrinkwrap.api.container.ManifestContainer#addAsManifestResource(java.io.File, java.lang.String)
*/
@Override
public T addAsManifestResource(File resource, String target) throws IllegalArgumentException {
@@ -21,7 +21,6 @@
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
-import org.jboss.shrinkwrap.impl.base.ShallowCopy;
import org.jboss.shrinkwrap.impl.base.container.EnterpriseContainerBase;
import org.jboss.shrinkwrap.impl.base.path.BasicPath;
@@ -78,18 +77,6 @@ public EnterpriseArchiveImpl(final Archive<?> delegate) {
super(EnterpriseArchive.class, delegate);
}
- /**
- * {@inheritDoc}
- *
- * @see Archive#shallowCopy()
- */
- @Override
- public EnterpriseArchiveImpl shallowCopy() {
- EnterpriseArchiveImpl newInstance = new EnterpriseArchiveImpl(getArchive().shallowCopy());
- ShallowCopy.shallowCopyContentTo(this, newInstance);
- return newInstance;
- }
-
// -------------------------------------------------------------------------------------||
// Required Implementations -----------------------------------------------------------||
// -------------------------------------------------------------------------------------||
Oops, something went wrong.

0 comments on commit dcf5f87

Please sign in to comment.