001    package hirondelle.web4jtools.metrics.images;
002    
003    import java.util.*;
004    import hirondelle.web4j.model.Check;
005    import hirondelle.web4j.model.ModelUtil;
006    import static hirondelle.web4j.util.Consts.FAILS;
007    import hirondelle.web4jtools.metrics.base.FileInfo;
008    import hirondelle.web4j.util.Util;
009    
010    /** 
011    * Model Object for an image, and all files that reference it.
012    * <P>This class is mutable. 
013    */
014    public final class ImageReference {
015    
016      /**
017      * Full constructor.
018      *  
019      * @param aFileInfo file info for the image file.
020      */
021      public ImageReference(FileInfo aFileInfo) {
022        fFileInfo = aFileInfo;
023        validateState();
024      }
025      
026      /** Add a file which references the image.  */
027      public void addReferenceFrom(FileInfo aFileInfo) {
028        fReferencingFiles.add(aFileInfo);
029      }
030      
031      /** Return the file information for the image itself.  */
032      public FileInfo getFileInfo() { return fFileInfo; }
033      
034      /** List all files that <em>reference</em> the image. */
035      public List<FileInfo> getReferencingFiles(){ return fReferencingFiles; }
036      
037      /** Return the number of files that reference the image. */
038      public Integer getNumReferences(){
039        return fReferencingFiles.size();
040      }
041      
042      @Override public String toString(){
043        return ModelUtil.toStringFor(this);
044      }
045      
046      @Override public boolean equals(Object aThat){
047        Boolean result = ModelUtil.quickEquals(this, aThat);
048        if ( result == null ) {
049          ImageReference that = (ImageReference)aThat;
050          result = ModelUtil.equalsFor(this.getSignificantFields(), that.getSignificantFields());
051        }
052        return result;
053      }
054      
055      @Override public int hashCode(){
056        //no caching - mutable
057        return ModelUtil.hashCodeFor(getSignificantFields());
058      }
059    
060      // PRIVATE //
061      private final FileInfo fFileInfo;
062      private final List<FileInfo> fReferencingFiles = new ArrayList<FileInfo>();
063    
064      private void validateState() {
065        StringBuilder errorMsg = new StringBuilder();
066        if ( FAILS == Check.required(fFileInfo) ) {
067          errorMsg.append("Name is required.");
068        }
069        if ( Util.textHasContent(errorMsg.toString()) ) {
070          throw new IllegalArgumentException(errorMsg.toString());
071        }
072      }
073      
074      private Object[] getSignificantFields(){
075        return new Object[] {fFileInfo, fReferencingFiles};
076      }
077    }