Commits

Anonymous committed 37c7b79

Restore "extra properties" to various Source and Source Factory classes and properties file;
Replace source/source factory methods with zipentry in signature with more general methods using inputStream and reportable
Modify zipmodule to use those new source methods
Set sealed = false in pom.xml so jar is NOT sealed (for shapefile classes)

Comments (0)

Files changed (11)

config/properties/module/display/displayer/org/jhove2/core/source/Source_displayer.properties

 # Positive means 1,2,3,...; NonPositive means ...,-2,-1,0
 http\://jhove2.org/terms/message/org/jhove2/core/source/Source/Messages	Always
 http\://jhove2.org/terms/property/org/jhove2/core/source/Source/ChildSources	Always
-http\://jhove2.org/terms/property/org/jhove2/core/source/Source/FileSystemProperties	Always
+http\://jhove2.org/terms/property/org/jhove2/core/source/Source/FileSystemProperties	Always
+http\://jhove2.org/terms/property/org/jhove2/core/source/Source/ExtraProperties	Always
 http\://jhove2.org/terms/property/org/jhove2/core/source/Source/Modules	Always
 http\://jhove2.org/terms/property/org/jhove2/core/source/Source/NumChildSources	IfNonZero
 http\://jhove2.org/terms/property/org/jhove2/core/source/Source/PresumptiveFormats	Always
 							<mainClass>org.jhove2.app.JHOVE2CommandLine</mainClass>
 						</manifest>
 						<manifestEntries>
-							<Sealed>true</Sealed>
+							<Sealed>false</Sealed>
 						</manifestEntries>
 					</archive>
  					<forceCreation>true</forceCreation>

src/main/java/org/jhove2/core/source/AbstractSource.java

 import org.jhove2.core.format.FormatIdentification;
 import org.jhove2.core.io.Input;
 import org.jhove2.core.reportable.AbstractReportable;
+import org.jhove2.core.reportable.Reportable;
 import org.jhove2.module.Module;
 import org.jhove2.persist.SourceAccessor;
 
 	/** Temporary file deletion flag; if true, delete on close. */
 	protected boolean deleteTempFileOnClose;
 	
+	/** Extra properties.  Extra properties are those not known at the time a
+	 * source unit is instantiated and are not associated with a particular
+	 * {@link org.jhove2.module.format.FormatModule}. */
+	protected List<Reportable> extraProperties;
+    	
 	/** File system properties, if the source is a physical file or directory
 	 * in the file system.
 	 */
 	 */
 	protected AbstractSource() {       
         this.deleteTempFileOnClose   = Invocation.DEFAULT_DELETE_TEMP_FILES_ON_CLOSE;
+        this.extraProperties = new ArrayList<Reportable>();
 		this.isAggregate     = false;
         this.isTemp          = false;
 		this.messages        = new ArrayList<Message>();		
 		}
 		return this.sourceAccessor.addChildSource(this, child);
 	}
+
+	   
+    /** Add an extra properties {@link org.jhove2.core.reportable.Reportable}
+     * to be associated with the source unit.  Extra properties are those not
+     * known at the time the source unit is instantiated and which are not
+     * associated with a particular {@link org.jhove2.module.format.FormatModule}.
+     * @param properties Extra properties reportable
+     * @return Source with extra properties added
+     * @throws JHOVE2Exception
+     */
+	@Override
+    public Source addExtraProperties(Reportable properties)
+        throws JHOVE2Exception
+    {
+	    return this.getSourceAccessor().addExtraProperties(this, properties);
+    }
     
 	/** Add a message to be associated with the source unit.
 	 * @param message Message to be associated with the source unit
 		}
 		return this.sourceAccessor.getChildSources(this);
 	}
+    
+    /** Get extra properties.  Extra properties are those not known at the
+     * time the source unit is instantiated but which are not associated with
+     * a particular {@link org.jhove2.module.format.FormatModule}.
+     * @return Extra properties
+     * @throws JHOVE2Exception
+     */
+    @Override
+    public List<Reportable> getExtraProperties()
+        throws JHOVE2Exception
+    {
+        return this.extraProperties;
+    }
 
     /**
      * Get {@link java.io.File} backing the source unit.

src/main/java/org/jhove2/core/source/AbstractSourceFactory.java

 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 import java.util.List;
 import java.util.zip.ZipEntry;
 
 import org.jhove2.core.JHOVE2;
 import org.jhove2.core.JHOVE2Exception;
+import org.jhove2.core.reportable.Reportable;
 
 import com.sleepycat.persist.model.Persistent;
 
  */
 @Persistent
 public abstract class AbstractSourceFactory
-    implements SourceFactory
+implements SourceFactory
 {
 	public AbstractSourceFactory(){
 		super();
 	 */
 	@Override
 	public Source getSource(JHOVE2 jhove2, String name)
-	    throws IOException, JHOVE2Exception
+	throws IOException, JHOVE2Exception
 	{
 		Source source = SourceFactoryUtil.getSource(jhove2, name);
 		source = source.getSourceAccessor().persistSource(source);
 	}
 
 	/** Get source from a file system object, either a file or a directory.
-     * @param jhove2 JHOVE2 framework object
+	 * @param jhove2 JHOVE2 framework object
 	 * @param file Object file
 	 * @see org.jhove2.core.source.SourceFactory#getSource(java.io.File)
 	 */
 	@Override
 	public Source getSource(JHOVE2 jhove2, File file)
-	    throws IOException, JHOVE2Exception
+	throws IOException, JHOVE2Exception
 	{
 		Source source = SourceFactoryUtil.getSource(jhove2, file);
 		source = source.getSourceAccessor().persistSource(source);
 	 */
 	@Override
 	public Source getSource(JHOVE2 jhove2, URL url)
-	    throws IOException, JHOVE2Exception
+	throws IOException, JHOVE2Exception
 	{
 		Source source = SourceFactoryUtil.getSource(jhove2, url);
 		source = source.getSourceAccessor().persistSource(source);
 		return source;
 	}
 
+//	/** Get source unit from a Zip file entry.
+//	 * @param zip Zip file
+//	 * 
+//	 * @param jhove2 JHOVE2 framework object
+//	 * @param entry Zip file entry
+//	 * @see org.jhove2.core.source.SourceFactory#getSource(java.lang.String, java.lang.String, int, java.util.zip.ZipFile, java.util.zip.ZipEntry)
+//	 */
+//	@Override
+//	public Source getSource(JHOVE2 jhove2, ZipFile zip, ZipEntry entry)
+//	throws IOException, JHOVE2Exception
+//	{
+//		Source source = SourceFactoryUtil.getSource(jhove2, zip, entry);
+//		source = source.getSourceAccessor().persistSource(source);
+//		return source;
+//	}
+
 	/** Get source unit from a Zip file entry.
 	 * @param zip Zip file
 	 * 
-     * @param jhove2 JHOVE2 framework object
+	 * @param jhove2 JHOVE2 framework object
 	 * @param entry Zip file entry
 	 * @see org.jhove2.core.source.SourceFactory#getSource(java.lang.String, java.lang.String, int, java.util.zip.ZipFile, java.util.zip.ZipEntry)
 	 */
 	@Override
-	public Source getSource(JHOVE2 jhove2, ZipFile zip, ZipEntry entry)
-	    throws IOException, JHOVE2Exception
+	public Source getSource(JHOVE2 jhove2, InputStream inputStream, String name, Reportable otherProperties)
+	throws IOException, JHOVE2Exception
 	{
-		Source source = SourceFactoryUtil.getSource(jhove2, zip, entry);
+		Source source = SourceFactoryUtil.getSource(jhove2, inputStream, name, otherProperties);
 		source = source.getSourceAccessor().persistSource(source);
 		return source;
 	}
 
-    /**
-     * Get source unit from a formatted object name, which can be a file, a.
-     * directory, or a URL. Note that a URL source unit requires the
-     * creation of a temporary file.
-     * 
-     * @param jhove2 JHOVE2 framework object
-     * @param name First formatted object name
-     * @param names Remaining formatted object names
-     * @return Source unit
-     * @throws FileNotFoundException
-     *             File not found
-     * @throws IOException
-     *             I/O exception instantiating source
-     * @throws JHOVE2Exception
-     */
+	/**
+	 * Get source unit from a formatted object name, which can be a file, a.
+	 * directory, or a URL. Note that a URL source unit requires the
+	 * creation of a temporary file.
+	 * 
+	 * @param jhove2 JHOVE2 framework object
+	 * @param name First formatted object name
+	 * @param names Remaining formatted object names
+	 * @return Source unit
+	 * @throws FileNotFoundException
+	 *             File not found
+	 * @throws IOException
+	 *             I/O exception instantiating source
+	 * @throws JHOVE2Exception
+	 */
 	@Override
-    public Source getSource(JHOVE2 jhove2, String name, String...names)
-        throws IOException, JHOVE2Exception
-    {
-        Source source = SourceFactoryUtil.getSource(jhove2, this, name, names);
-        source = source.getSourceAccessor().persistSource(source);
-        return source;
-    }
-   
+	public Source getSource(JHOVE2 jhove2, String name, String...names)
+	throws IOException, JHOVE2Exception
+	{
+		Source source = SourceFactoryUtil.getSource(jhove2, this, name, names);
+		source = source.getSourceAccessor().persistSource(source);
+		return source;
+	}
+
 	/** Get source unit from a list of formatted object names, which may be
 	 * files, directories, or URLs.  Note that URL source units require the
 	 * creation of temporary files.
-     * @param jhove2 JHOVE2 framework object
+	 * @param jhove2 JHOVE2 framework object
 	 * @param names Formatted object names
-     * @param bufferSize Buffer size (for creating temporary file)
+	 * @param bufferSize Buffer size (for creating temporary file)
 	 * @see org.jhove2.core.source.SourceFactory#getSource(java.util.List. java.io.File, java.lang.String, java.lang.String, int)
 	 */
 	@Override
 	public Source getSource(JHOVE2 jhove2, List<String> names)
-	    throws IOException, JHOVE2Exception
+	throws IOException, JHOVE2Exception
 	{
 		Source source = SourceFactoryUtil.getSource(jhove2, names);
 		source = source.getSourceAccessor().persistSource(source);
 		return source;
 	}
-    
-    /** Get ByteStream source.
-     * @param jhove2 JHOVE2 framework object
-     * @param parent Parent source unit
-     * @param offset Starting offset
-     * @param size   Size
-     * @param name   Name, if known
-     * @return ByteStream source unit
-     * @throws JHOVE2Exception
-     */
-    @Override
-    public ByteStreamSource getByteStreamSource(JHOVE2 jhove2, Source parent,
-                                                long offset, long size,
-                                                String name) 
-        throws IOException, JHOVE2Exception
-    {
-        ByteStreamSource source =
-            SourceFactoryUtil.getByteStreamSource(jhove2, parent, offset, size,
-                                                  name);
-        source = (ByteStreamSource) source.getSourceAccessor().persistSource(source);
-        return source;      
-    }
-    
+
+	/** Get ByteStream source.
+	 * @param jhove2 JHOVE2 framework object
+	 * @param parent Parent source unit
+	 * @param offset Starting offset
+	 * @param size   Size
+	 * @param name   Name, if known
+	 * @return ByteStream source unit
+	 * @throws JHOVE2Exception
+	 */
+	@Override
+	public ByteStreamSource getByteStreamSource(JHOVE2 jhove2, Source parent,
+			long offset, long size,
+			String name) 
+	throws IOException, JHOVE2Exception
+	{
+		ByteStreamSource source =
+			SourceFactoryUtil.getByteStreamSource(jhove2, parent, offset, size,
+					name);
+		source = (ByteStreamSource) source.getSourceAccessor().persistSource(source);
+		return source;      
+	}
+
 	/** Get Clump source.
 	 * @param jhove2 JHOVE2 framework object */
 	@Override
 		source = (ClumpSource) source.getSourceAccessor().persistSource(source);
 		return source;
 	}
+
+//	/**
+//	 * Utility method to create empty non-file system DirectorySource
+//	 * @param jhove2 JHOVE2 framework object
+//	 * @param name   Directory name 
+//	 * @return Directory source unit
+//	 * @throws JHOVE2Exception 
+//	 * @throws IOException 
+//	 * @throws FileNotFoundException 
+//	 */
+//	@Override
+//	public DirectorySource getDirectorySource(JHOVE2 jhove2, String name)
+//	throws IOException, JHOVE2Exception
+//	{
+//		return getDirectorySource(jhove2, name, false);
+//	}
 	
     /**
      * Utility method to create empty non-file system DirectorySource
      * @param jhove2 JHOVE2 framework object
      * @param name   Directory name 
+     * @param isFileSystemDirectory boolean indicating if Directory is "actual" or just "virtual" 
+     *           artifact of source processing
      * @return Directory source unit
+     * @throws IOException
      * @throws JHOVE2Exception 
-     * @throws IOException 
-     * @throws FileNotFoundException 
      */
 	@Override
-    public DirectorySource getDirectorySource(JHOVE2 jhove2, String name)
-        throws IOException, JHOVE2Exception
-    {
-	    DirectorySource source = SourceFactoryUtil.getDirectorySource(jhove2, name);
-	    source = (DirectorySource) source.getSourceAccessor().persistSource(source);
-	    return source;
-    }
+	public DirectorySource getDirectorySource(JHOVE2 jhove2, String name, boolean isFileSystemDirectory)
+	throws IOException, JHOVE2Exception
+	{
+		DirectorySource source = SourceFactoryUtil.getDirectorySource(jhove2, name, isFileSystemDirectory);
+		source = (DirectorySource) source.getSourceAccessor().persistSource(source);
+		return source;
+	}
 
 	/* Get FileSet source.
 	 * @param jhove2 JHOVE2 framework object

src/main/java/org/jhove2/core/source/Source.java

 	 */
 	public Source addChildSource(Source child) throws JHOVE2Exception;
 	
+	/** Add an extra properties {@link org.jhove2.core.reportable.Reportable}
+	 * to be associated with the source unit.  Extra properties are those not
+	 * known at the time the source unit is instantiated and which are not
+	 * associated with a particular {@link org.jhove2.module.format.FormatModule}.
+	 * @param properties Extra properties reportable
+	 * @return Source with extra properties added
+	 * @throws JHOVE2Exception
+	 */
+	public Source addExtraProperties(Reportable properties) throws JHOVE2Exception;
+	
 	/** Add a message to be associated with the source unit.
 	 * @param message Message to be associated with the source unit
 	 * @return Source with message added
 	 */
 	@ReportableProperty(order=8, value="Child source units.")
 	public List<Source> getChildSources() throws JHOVE2Exception;
+	
+	/** Get extra properties.  Extra properties are those not known at the
+	 * time the source unit is instantiated but which are not associated with
+	 * a particular {@link org.jhove2.module.format.FormatModule}.
+	 * @return Extra properties
+	 * @throws JHOVE2Exception
+	 */
+	@ReportableProperty(order=2, value="Extra properties.")
+	public List<Reportable> getExtraProperties() throws JHOVE2Exception;
 
 	/**
 	 * Get temporary file deletion flag; if true, delete on close.

src/main/java/org/jhove2/core/source/SourceFactory.java

 
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URL;
 import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 
 import org.jhove2.core.JHOVE2;
 import org.jhove2.core.JHOVE2Exception;
+import org.jhove2.core.reportable.Reportable;
 import org.jhove2.persist.SourceAccessor;
 
 /**
 	public Source getSource(JHOVE2 jhove2, URL url)
 	    throws IOException, JHOVE2Exception;
 
+//	/**
+//	 * Get source unit from a Zip file entry by creating a temporary file.
+//	 * 
+//     * @param jhove2 JHOVE2 framework object
+//     * @param zip
+//     *            Zip file
+//     * @param entry
+//     *            Zip file entry
+//	 * @return Source unit
+//	 * @throws IOException
+//	 *             I/O exception instantiating source
+//	 * @throws JHOVE2Exception 
+//	 */
+//	public Source getSource(JHOVE2 jhove2, ZipFile zip, ZipEntry entry)
+//		throws IOException, JHOVE2Exception;
 	/**
-	 * Get source unit from a Zip file entry by creating a temporary file.
 	 * 
-     * @param jhove2 JHOVE2 framework object
-     * @param zip
-     *            Zip file
-     * @param entry
-     *            Zip file entry
-	 * @return Source unit
+	 * @param jhove2
+	 * @param inputStream
+	 * @param name
+	 * @param otherProperties
+	 * @return
 	 * @throws IOException
-	 *             I/O exception instantiating source
-	 * @throws JHOVE2Exception 
+	 * @throws JHOVE2Exception
 	 */
-	public Source getSource(JHOVE2 jhove2, ZipFile zip, ZipEntry entry)
-		throws IOException, JHOVE2Exception;
+	public Source getSource(JHOVE2 jhove2, InputStream inputStream, String name, Reportable otherProperties)
+    throws IOException, JHOVE2Exception;
 
     /**
      * Get FileSet source unit from a formatted object name, which can be a file, a.
 	 */
 	public ClumpSource getClumpSource(JHOVE2 jhove2) throws JHOVE2Exception;
 	   
+//    /**
+//     * Utility method to create empty non-file system DirectorySource
+//     * @param jhove2 JHOVE2 framework object
+//     * @param name   Directory name 
+//     * @return Directory source unit
+//     * @throws IOException
+//     * @throws JHOVE2Exception 
+//     */
+//    public DirectorySource getDirectorySource(JHOVE2 jhove2, String name)
+//        throws IOException, JHOVE2Exception;
+    
     /**
      * Utility method to create empty non-file system DirectorySource
      * @param jhove2 JHOVE2 framework object
      * @param name   Directory name 
+     * @param isFileSystemDirectory boolean indicating if Directory is "actual" or just "virtual" 
+     *           artifact of source processing
      * @return Directory source unit
      * @throws IOException
      * @throws JHOVE2Exception 
      */
-    public DirectorySource getDirectorySource(JHOVE2 jhove2, String name)
-        throws IOException, JHOVE2Exception;
-    
+    public DirectorySource getDirectorySource(JHOVE2 jhove2, String name, boolean isFileSystemDirectory)
+	throws IOException, JHOVE2Exception;
 	/**
 	 * Utility method to create empty FileSetSource
      * @param jhove2 JHOVE2 framework object

src/main/java/org/jhove2/core/source/SourceFactoryUtil.java

 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
+import org.jhove2.core.Digest;
 import org.jhove2.core.Invocation;
 import org.jhove2.core.JHOVE2;
 import org.jhove2.core.JHOVE2Exception;
+import org.jhove2.core.reportable.Reportable;
+import org.jhove2.module.digest.AbstractArrayDigester;
+import org.jhove2.module.digest.CRC32Digester;
+import org.jhove2.module.format.zip.ZipEntryProperties;
 
 /**
  * Factory for JHOVE2 file and directory source units.
 	 * @throws JHOVE2Exception 
 	 */
 	public static synchronized Source getSource(JHOVE2 jhove2, String name)
-		throws IOException, JHOVE2Exception
+	throws IOException, JHOVE2Exception
 	{
-	    Source source = null;
-	    
-	    /* First check if the name is a URL. If not, assume it's a file or
-	     * directory name.
-	     */
-        try{
-            URL url = new URL(name);
-            source = SourceFactoryUtil.getSource(jhove2, url);
-        }
-        catch (MalformedURLException m){
-            File file = new File(name);
-            source = SourceFactoryUtil.getSource(jhove2, file);
-        }
-        
+		Source source = null;
+
+		/* First check if the name is a URL. If not, assume it's a file or
+		 * directory name.
+		 */
+		try{
+			URL url = new URL(name);
+			source = SourceFactoryUtil.getSource(jhove2, url);
+		}
+		catch (MalformedURLException m){
+			File file = new File(name);
+			source = SourceFactoryUtil.getSource(jhove2, file);
+		}
+
 		return source;
 	}
 
 	/**
 	 * Get source unit from a Java {@link java.io.File}.
 	 * 
-     * @param jhove2 JHOVE2 framework object
+	 * @param jhove2 JHOVE2 framework object
 	 * @param file
 	 *            Java {@link java.io.File}
 	 * @return Source unit
 	 * @throws JHOVE2Exception 
 	 */
 	public static synchronized Source getSource(JHOVE2 jhove2, File file)
-		throws IOException, JHOVE2Exception
+	throws IOException, JHOVE2Exception
 	{
 		Source source = null;
 		if (file.isDirectory()) {		
 		else{
 			source = new FileSource(jhove2, file);
 		}
-		
+
 		return source;
 	}
 
 	/**
 	 * Get source unit from a URL by creating a local temporary file.
-     * @param jhove2 JHOVE2 framework object
-     * @param url URL
+	 * @param jhove2 JHOVE2 framework object
+	 * @param url URL
 	 * @return URL source unit
 	 * @throws IOException
 	 *             I/O exception instantiating source
 	 */
 	public static synchronized Source getSource(JHOVE2 jhove2, URL url)
-		throws IOException
+	throws IOException
 	{
 		Source source = new URLSource(jhove2, url);
 		return source;
 	}
 
-	/**
-	 * Get source unit from a Zip file entry by creating a temporary file.
-	 * @param jhove2 JHOVE2 framework object
-     * @param zip
-     *            Zip file
-     * @param entry
-     *            Zip file entry
-	 * @return Source unit
-	 * @throws IOException
-	 *             I/O exception instantiating source
-	 * @throws JHOVE2Exception 
-	 */
-	public static synchronized Source getSource(JHOVE2 jhove2, ZipFile zip,
-	                                            ZipEntry entry)
-		throws IOException, JHOVE2Exception
-	{
+//	/**
+//	 * Get source unit from a Zip file entry by creating a temporary file.
+//	 * @param jhove2 JHOVE2 framework object
+//	 * @param zip
+//	 *            Zip file
+//	 * @param entry
+//	 *            Zip file entry
+//	 * @return Source unit
+//	 * @throws IOException
+//	 *             I/O exception instantiating source
+//	 * @throws JHOVE2Exception 
+//	 */
+//	public static synchronized Source getSource(JHOVE2 jhove2, ZipFile zip,
+//			ZipEntry entry)
+//	throws IOException, JHOVE2Exception
+//	{
+//		Source source = null;
+//		String name = entry.getName();
+//		//		if (entry.isDirectory()) {
+//		//		    /* Delete trailing slash from path name, if necessary. Although this
+//		//		     * always should be a forward slash (/), in practice a backward slash
+//		//		     * \) may be found.
+//		//		     */
+//		//		    int in = name.lastIndexOf('/');
+//		//		    if (in < 0) {
+//		//		        in = name.lastIndexOf('\\');
+//		//		    }
+//		//		    if (in == name.length() - 1) {
+//		//		        name = name.substring(0, in);
+//		//		    }
+//		//		    source = new DirectorySource(jhove2, name, false);        
+//		//		}
+//		//		else {
+//		/* Recover the filename from the pathname. Although the path
+//		 * separator always should be a forward slash (/), in practice a
+//		 * backward slash (\) may be found.
+//		 */
+//		int in = name.lastIndexOf('/');
+//		if (in < 0) {
+//			in = name.lastIndexOf('\\');
+//		}
+//		if (in > -1) {
+//			name = name.substring(in+1);
+//		}
+//		/* Create a temporary Java {@link java.io.File} to represent the
+//		 * file entry.
+//		 */
+//		InputStream stream = zip.getInputStream(entry);
+//		Invocation inv = jhove2.getInvocation();
+//		File file = AbstractSource.createTempFile(stream, name,
+//				inv.getTempDirectoryFile(),
+//				inv.getTempPrefix(),
+//				inv.getTempSuffix(),
+//				inv.getBufferSize());
+//		stream.close();
+//
+//		source = new FileSource(jhove2, file, false);
+//		source.setIsTemp(true);
+//
+//		/* This is a temporary fix.  We need to keep the temporary backing
+//		 * files for Zip components in case we need to later get an
+//		 * {@link java.io.InputStream} on the component
+//		 * (Source.getInputStream()) to pass to a third-party package that
+//		 * doesn't support {@link org.jhove2.core.io.Input}s.
+//		 * 
+//		 * Note that the temporary files will accumulate in the temporary
+//		 * directory after termination.
+//		 * 
+//		 * TODO: Find a better mechanism for dealing with this problem
+//		 * in the recursive processing model.
+//		 */
+//		source.setDeleteTempFileOnClose(false);
+//		//		}
+//
+//		/* Get the entry-specific properties. */
+//		long crc = entry.getCrc();
+//		Digest crc32 = new Digest(AbstractArrayDigester.toHexString(crc),
+//				CRC32Digester.ALGORITHM);
+//		ZipEntryProperties properties =
+//			new ZipEntryProperties(name, entry.getCompressedSize(), crc32,
+//					entry.getComment(),
+//					new Date(entry.getTime()));
+//		source.addExtraProperties(properties);
+//
+//		return source;
+//	}	
+
+	public static synchronized Source getSource(JHOVE2 jhove2, 
+			InputStream stream, 
+			String name,
+			Reportable otherProperties)
+	throws IOException, JHOVE2Exception
+	{	
 		Source source = null;
-        String name = entry.getName();
-		if (entry.isDirectory()) {
-		    /* Delete trailing slash from path name, if necessary. Although this
-		     * always should be a forward slash (/), in practice a backward slash
-		     * \) may be found.
-		     */
-		    int in = name.lastIndexOf('/');
-		    if (in < 0) {
-		        in = name.lastIndexOf('\\');
-		    }
-		    if (in == name.length() - 1) {
-		        name = name.substring(0, in);
-		    }
-		    source = new DirectorySource(jhove2, name, false);        
-		}
-		else {
-		    /* Recover the filename from the pathname. Although the path
-		     * separator always should be a forward slash (/), in practice a
-		     * backward slash (\) may be found.
-		     */
-		    int in = name.lastIndexOf('/');
-		    if (in < 0) {
-		        in = name.lastIndexOf('\\');
-		    }
-		    if (in > -1) {
-		        name = name.substring(in+1);
-		    }
-		    /* Create a temporary Java {@link java.io.File} to represent the
-		     * file entry.
-		     */
-	        InputStream stream = zip.getInputStream(entry);
-	        Invocation inv = jhove2.getInvocation();
-	        File file = AbstractSource.createTempFile(stream, name,
-	                                                  inv.getTempDirectoryFile(),
-	                                                  inv.getTempPrefix(),
-	                                                  inv.getTempSuffix(),
-	                                                  inv.getBufferSize());
-            stream.close();
-            
-	        source = new FileSource(jhove2, file, false);
-	        source.setIsTemp(true);
-	        
-	        /* This is a temporary fix.  We need to keep the temporary backing
-	         * files for Zip components in case we need to later get an
-	         * {@link java.io.InputStream} on the component
-	         * (Source.getInputStream()) to pass to a third-party package that
-	         * doesn't support {@link org.jhove2.core.io.Input}s.
-	         * 
-	         * Note that the temporary files will accumulate in the temporary
-	         * directory after termination.
-	         * 
-	         * TODO: Find a better mechanism for dealing with this problem
-	         * in the recursive processing model.
-	         */
-            source.setDeleteTempFileOnClose(false);
-		}
+		Invocation inv = jhove2.getInvocation();
+		File file = AbstractSource.createTempFile(stream, name,
+				inv.getTempDirectoryFile(),
+				inv.getTempPrefix(),
+				inv.getTempSuffix(),
+				inv.getBufferSize());
+		stream.close();
+		source = new FileSource(jhove2, file, false);
+		source.setIsTemp(true);
+
+		/* This is a temporary fix.  We need to keep the temporary backing
+		 * files for Zip components in case we need to later get an
+		 * {@link java.io.InputStream} on the component
+		 * (Source.getInputStream()) to pass to a third-party package that
+		 * doesn't support {@link org.jhove2.core.io.Input}s.
+		 * 
+		 * Note that the temporary files will accumulate in the temporary
+		 * directory after termination.
+		 * 
+		 * TODO: Find a better mechanism for dealing with this problem
+		 * in the recursive processing model.
+		 */
+		source.setDeleteTempFileOnClose(false);
+		source.addExtraProperties(otherProperties);
 		return source;
-	}	
-	
+	}
 	/**
 	 * Make Source from list of formatted objects, which may be files,
 	 * directories. and URLS
 	 * 
-     * @param jhove2 JHOVE2 framework object
+	 * @param jhove2 JHOVE2 framework object
 	 * @param sourceFactory 
 	 * 			SourceFactory which configures accessors for this source
-     * @param name First object name, which may be a file, directory, or URL
-     * @param names
-     *            Additional object names, which may be files, directories, or URLs
+	 * @param name First object name, which may be a file, directory, or URL
+	 * @param names
+	 *            Additional object names, which may be files, directories, or URLs
 	 * @return Source
 	 * @throws IOException
 	 * @throws JHOVE2Exception
 	 */
 	public static synchronized Source getSource(JHOVE2 jhove2, 
-	                                            SourceFactory sourceFactory,
-	                                            String name, String...names)
-		throws IOException, JHOVE2Exception
+			SourceFactory sourceFactory,
+			String name, String...names)
+	throws IOException, JHOVE2Exception
 	{
-	    List<String> list = new ArrayList<String>();
-        list.add(name);
-        if (names != null && names.length > 0) {
-            for (int i = 0; i < names.length; i++) {
-                list.add(names[i]);
-            }
-        }
-        return SourceFactoryUtil.getSource(jhove2, list);
+		List<String> list = new ArrayList<String>();
+		list.add(name);
+		if (names != null && names.length > 0) {
+			for (int i = 0; i < names.length; i++) {
+				list.add(names[i]);
+			}
+		}
+		return SourceFactoryUtil.getSource(jhove2, list);
 	}
-	   
-    /**
-     * Make Source from list of formatted objects, which may be files,
-     * directories. and URLS
-     * @param jhove2 JHOVE2 framework object
-     * @param names
-     *            Object names, which may be files, directories, or URLs
-     * @param sourceFactory 
-     *          SourceFactory which configures accessors for this source
-     * @return Source
-     * @throws IOException
-     * @throws JHOVE2Exception
-     */
-    public static synchronized Source getSource(JHOVE2 jhove2,
-                                                List<String> pathNames)
-        throws IOException, JHOVE2Exception
-    {
-        Source source = null;       
-        if (pathNames.size() == 1) {
-            String name = pathNames.get(0);
-            source = SourceFactoryUtil.getSource(jhove2, name);        
-        }
-        else {
-            source = new FileSetSource(jhove2);
-            Iterator<String> iter = pathNames.iterator();
-            while (iter.hasNext()) {
-                String name = iter.next();
-                Source src = SourceFactoryUtil.getSource(jhove2, name);
-                src = ((FileSetSource)source).addChildSource(src);
-            }
-        }
-        
-        return source;
-    }
-    
-    /** Create new ByteStreamSource
-     * @param jhove2 JHOVE2 framework object
-     * @param parent Parent source unit
-     * @param offset Starting byte offset
-     * @param size   Size of byte stream
-     * @param name   Name, if known
-     * @return Byte stream source unit
-     * @throws IOException
-     * @throws JHOVE2Exception
-     */
-    public static synchronized ByteStreamSource getByteStreamSource(JHOVE2 jhove2,
-                                                    Source parent, long offset,
-                                                    long size, String name)
-        throws IOException, JHOVE2Exception
-    {
-        ByteStreamSource source = new ByteStreamSource(jhove2, parent, offset,
-                                                       size, name);
-        return source;
-    }    
+
+	/**
+	 * Make Source from list of formatted objects, which may be files,
+	 * directories. and URLS
+	 * @param jhove2 JHOVE2 framework object
+	 * @param names
+	 *            Object names, which may be files, directories, or URLs
+	 * @param sourceFactory 
+	 *          SourceFactory which configures accessors for this source
+	 * @return Source
+	 * @throws IOException
+	 * @throws JHOVE2Exception
+	 */
+	public static synchronized Source getSource(JHOVE2 jhove2,
+			List<String> pathNames)
+	throws IOException, JHOVE2Exception
+	{
+		Source source = null;       
+		if (pathNames.size() == 1) {
+			String name = pathNames.get(0);
+			source = SourceFactoryUtil.getSource(jhove2, name);        
+		}
+		else {
+			source = new FileSetSource(jhove2);
+			Iterator<String> iter = pathNames.iterator();
+			while (iter.hasNext()) {
+				String name = iter.next();
+				Source src = SourceFactoryUtil.getSource(jhove2, name);
+				src = ((FileSetSource)source).addChildSource(src);
+			}
+		}
+
+		return source;
+	}
+
+	/** Create new ByteStreamSource
+	 * @param jhove2 JHOVE2 framework object
+	 * @param parent Parent source unit
+	 * @param offset Starting byte offset
+	 * @param size   Size of byte stream
+	 * @param name   Name, if known
+	 * @return Byte stream source unit
+	 * @throws IOException
+	 * @throws JHOVE2Exception
+	 */
+	public static synchronized ByteStreamSource getByteStreamSource(JHOVE2 jhove2,
+			Source parent, long offset,
+			long size, String name)
+	throws IOException, JHOVE2Exception
+	{
+		ByteStreamSource source = new ByteStreamSource(jhove2, parent, offset,
+				size, name);
+		return source;
+	}    
 	/**
 	 * Create new ClumpSource
 	 * @param sourceFactory
 	 * 			SourceFactory which configures accessors for this source
-     * @param jhove2 JHOVE2 framework object
+	 * @param jhove2 JHOVE2 framework object
 	 * @return Clump source unit
 	 * @throws JHOVE2Exception 
 	 */
 	public static synchronized ClumpSource getClumpSource(JHOVE2 jhove2) 
-	    throws JHOVE2Exception
+	throws JHOVE2Exception
 	{		
 		ClumpSource source = new ClumpSource(jhove2);
 		return source;
 	}
-	   
-    /**
-     * Create empty non-file system DirectorySource
-     * @param jhove2 JHOVE2 framework object
-     * @param name   Directory name 
-     * @throws JHOVE2Exception 
-     * @throws IOException 
-     */
+
+	/**
+	 * Create empty non-file system DirectorySource
+	 * @param jhove2 JHOVE2 framework object
+	 * @param name   Directory name 
+	 * @param isFileSystemDirectory boolean indicating if Directory is "actual" or just "virtual" 
+	 *           artifact of source processing
+	 * @throws JHOVE2Exception 
+	 * @throws IOException 
+	 */
 	public static synchronized DirectorySource getDirectorySource(JHOVE2 jhove2,
-	                                                              String name)
-	    throws IOException, JHOVE2Exception 
+			String name,
+			boolean isFileSystemDirectory)
+	throws IOException, JHOVE2Exception 
 	{
-	    File file = new File(name);
-	    return new DirectorySource(jhove2, file, false);
+		File file = new File(name);
+		return new DirectorySource(jhove2, file, isFileSystemDirectory);
 	}
-	
+
 	/**
 	 * Create new empty FileSetSource
-     * @param jhove2 JHOVE2 framework object
+	 * @param jhove2 JHOVE2 framework object
 	 * @return FileSet source unit
 	 */
 	public static synchronized FileSetSource getFileSetSource(JHOVE2 jhove2) {

src/main/java/org/jhove2/module/format/zip/ZipModule.java

 import java.io.EOFException;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.Date;
     
     /** Zip64 end of central directory locator signature. */
     public static final int ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE = 0x07064b50;
-    	
+	
 	/** Validation status. */
 	protected Validity isValid;
 	
-	/** list of properites of each ZipFile entry */
-	protected List<ZipEntryProperties> zipEntryProperties;
-	
 	/**
 	 * Instantiate a new <code>ZipModule</code>.
 	 * 
     		FormatModuleAccessor formatModuleAccessor) {
 		super(VERSION, RELEASE, RIGHTS, format, formatModuleAccessor);
 		this.isValid = Validity.Undetermined;
-		this.zipEntryProperties = new ArrayList<ZipEntryProperties>();
 	}
 	
 	public ZipModule(){
 	    		if (factory == null){
 	    			throw new JHOVE2Exception("JHOVE2 SourceFactory is null");
 	    		}
+	    		
 	    		/* (1) Identify all directories that are explicit entries. */ 
 	            while (en.hasMoreElements()) {
-	                ZipEntry entry = en.nextElement();	                
+	                ZipEntry entry = en.nextElement();
 	                if (entry.isDirectory()) {
-	                    Source src =
-	                    	factory.getSource(jhove2, zip, entry);
+	                	 String name = entry.getName();
+	                	 /* Delete trailing slash from path name, if necessary. Although this
+	        		     * always should be a forward slash (/), in practice a backward slash
+	        		     * \) may be found.
+	        		     */
+	        		    int in = name.lastIndexOf('/');
+	        		    if (in < 0) {
+	        		        in = name.lastIndexOf('\\');
+	        		    }
+	        		    if (in == name.length() - 1) {
+	        		        name = name.substring(0, in);
+	        		    }
+//	                    Source src =
+//	                    	factory.getSource(jhove2, zip, entry);
+	        		    Source src =
+	        		    		factory.getDirectorySource(jhove2, name, false);
 	                    if (src != null) {
+	                    	/* Get the entry-specific properties. */
+		        	        long crc = entry.getCrc();
+		        	        Digest crc32 = new Digest(AbstractArrayDigester.toHexString(crc),
+		        	                                  CRC32Digester.ALGORITHM);
+		        			ZipEntryProperties properties =
+		        			    new ZipEntryProperties(name, entry.getCompressedSize(), crc32,
+		        			                           entry.getComment(),
+		        			                           new Date(entry.getTime()));
+		        			src = src.addExtraProperties(properties);
+		        			
 	                        String key = entry.getName();
 	                        /* Remove trailing slash. Although this always
 	                         * should be a forward slash (/), in practice a
 	            en = zip.entries();
 	            while (en.hasMoreElements()) {
 	                ZipEntry entry = en.nextElement();
-	                // capture reportable features of each entry
 	                String name = entry.getName();
-	                long crc = entry.getCrc();
-	                Digest crc32 = new Digest(AbstractArrayDigester.toHexString(crc),
-	                                          CRC32Digester.ALGORITHM);
-	        		ZipEntryProperties properties =
-	        		    new ZipEntryProperties(name, entry.getCompressedSize(), crc32,
-	        		                           entry.getComment(),
-	        		                           new Date(entry.getTime()));
-	        		this.getZipEntryProperties().add(properties);
 	                if (entry.isDirectory()) {
                         /* Remove trailing slash. Although this always should
                          * be a forward slash (/), in practice a backward
                         }
 	                }
 	                else {  /* Entry is a file. */
-	                    Source src =
-	                    	factory.getSource(jhove2, zip, entry);
+//	                    Source src =
+//	                    	factory.getSource(jhove2, zip, entry);
+	            		/* Recover the filename from the pathname. Although the path
+	            		 * separator always should be a forward slash (/), in practice a
+	            		 * backward slash (\) may be found.
+	            		 */
+	            		int in = name.lastIndexOf('/');
+	            		if (in < 0) {
+	            			in = name.lastIndexOf('\\');
+	            		}
+	            		if (in > -1) {
+	            			name = name.substring(in+1);
+	            		}
+	            		/* Create a temporary Java {@link java.io.File} to represent the
+	            		 * file entry.
+	            		 */
+	            		InputStream stream = zip.getInputStream(entry);
+	            		/* Get the entry-specific properties. */
+	            		long crc = entry.getCrc();
+	            		Digest crc32 = new Digest(AbstractArrayDigester.toHexString(crc),
+	            				CRC32Digester.ALGORITHM);
+	            		ZipEntryProperties properties =
+	            			new ZipEntryProperties(name, entry.getCompressedSize(), crc32,
+	            					entry.getComment(),
+	            					new Date(entry.getTime()));
+	            		Source src = 
+	            			factory.getSource(jhove2, stream, name, properties);
 	                    if (src != null) {
 	                        /* Check if the file pathname includes a directory
 	                         * component. Although the path separator always
 	                         * should be a forward slash (/), in practice a
 	                         * backward slash (\) may be found.
 	                         */
-	                        int in = name.lastIndexOf('/');
+	                    	name = entry.getName();
+	                        in = name.lastIndexOf('/');
 	                        if (in < 0) {
 	                            in = name.lastIndexOf('\\');
 	                        }
     public Coverage getCoverage() {
         return COVERAGE;
     }
-
-    /**
-     * Get reportable properties of ZipEntires
-     * @return List of ZipEntry reportable properties
-     */
-    @ReportableProperty(order=2, value="Zip file entries properties")
-	public List<ZipEntryProperties> getZipEntryProperties() {
-		return zipEntryProperties;
-	}
+    
+//    /** Get Zip file entries.
+//     * @return Zip file entries
+//     */
+//    @ReportableProperty(order=1, value="Zip file entries")
+//    public List<ZipFileEntry> getZipFileEntries() {
+//        return this.entries;
+//    }
     
     /** Get validity.
      * @return Validity
                 /* If the directory is not in the map, add it. */
                 Source src = map.get(key);
                 if (src == null) {
-                    src = factory.getDirectorySource(jhove2, key);
+                    src = factory.getDirectorySource(jhove2, key, false);
                     src = parent.addChildSource(src);
                     map.put(key, src);
                     parent = src;
             }
         }
     }
-
 }

src/main/java/org/jhove2/persist/SourceAccessor.java

 import org.jhove2.core.JHOVE2Exception;
 import org.jhove2.core.Message;
 import org.jhove2.core.format.FormatIdentification;
+import org.jhove2.core.reportable.Reportable;
 import org.jhove2.core.source.Source;
 import org.jhove2.module.Module;
 
 	 */
 	public Source addChildSource(Source parentSource, Source childSource) throws JHOVE2Exception;
     
+    /** Add an extra properties {@link org.jhove2.core.reportable.Reportable}
+     * to be associated with the source unit.  Extra properties are those not
+     * known at the time the source unit is instantiated but which are not
+     * associated with a particular {@link org.jhove2.module.format.FormatModule}.
+     * @param source     Source to which the properties are added
+     * @param properties Extra properties reportable
+     * @return Source with extra properties added
+     * @throws JHOVE2Exception
+     */
+    public Source addExtraProperties(Source source, Reportable properties) throws JHOVE2Exception;
+    
 	/**
 	 * Get child Sources of a Source
 	 * @param parentSource whose children are to be returned

src/main/java/org/jhove2/persist/berkeleydpl/BerkeleyDbSourceAccessor.java

 		}
 		return childSource;
 	}
+	 
+    /** Add an extra properties {@link org.jhove2.core.reportable.Reportable}
+     * to be associated with the source unit.  Extra properties are those not
+     * known at the time the source unit is instantiated but which are not
+     * associated with a particular {@link org.jhove2.module.format.FormatModule}.
+     * @param properties Extra properties reportable
+     * @return Source with extra properties added
+     * @throws JHOVE2Exception
+     */
+	@Override
+    public Source addExtraProperties(Source source, Reportable properties)
+        throws JHOVE2Exception
+    {
+	    if (source != null && properties != null){
+	        source.getExtraProperties().add(properties);
+	        source = this.persistSource(source);
+	    }
+	    return source;
+    }
     
 	/* (non-Javadoc)
 	 * @see org.jhove2.persist.SourceAccessor#addModule(org.jhove2.core.source.Source, org.jhove2.module.Module)

src/main/java/org/jhove2/persist/inmemory/InMemorySourceAccessor.java

 import org.jhove2.core.JHOVE2Exception;
 import org.jhove2.core.Message;
 import org.jhove2.core.format.FormatIdentification;
+import org.jhove2.core.reportable.Reportable;
 import org.jhove2.core.source.Source;
 import org.jhove2.module.Module;
 import org.jhove2.persist.SourceAccessor;
 public class InMemorySourceAccessor implements SourceAccessor {
 	/** Child source units. */
 	protected List<Source> children;
+	
+	/** Extra properties of the source.  Extra properties are those not known
+	 * at the time the source is instantiated and not associated with a
+	 * specific {@link org.jhove2.module.format.FormatModule}.
+	 */
+	protected List<Reportable> extraProperties;
+	
 	/** Modules which processed this Source */
 	protected List<Module> modules;
 	/** Source for which this is accessor*/
 	public InMemorySourceAccessor(){
 		super();
 		this.children        = new ArrayList<Source>();
+		this.extraProperties = new ArrayList<Reportable>();
 		this.modules         = new ArrayList<Module>();
 	}
 	
 		}
 		return childSource;
 	}
+  
+    /** Add an extra properties {@link org.jhove2.core.reportable.Reportable}
+     * to be associated with the source unit.  Extra properties are those not
+     * known at the time the source unit is instantiated but which are not
+     * associated with a particular {@link org.jhove2.module.format.FormatModule}.
+     * @param properties Extra properties reportable
+     * @return Source with extra properties added
+     * @throws JHOVE2Exception
+     */
+	@Override
+    public Source addExtraProperties(Source source, Reportable properties)
+        throws JHOVE2Exception
+    {
+        source.getExtraProperties().add(properties);
+        return  source;
+    }
     
 	/* (non-Javadoc)
 	 * @see org.jhove2.persist.SourceAccessor#addModule(org.jhove2.core.source.Source, org.jhove2.module.Module)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.