001 package hirondelle.web4jtools.metrics.base; 002 003 import hirondelle.web4j.model.ModelCtorException; 004 import hirondelle.web4j.security.SafeText; 005 import hirondelle.web4j.model.Check; 006 import hirondelle.web4j.model.ModelUtil; 007 import hirondelle.web4j.model.Validator; 008 import java.io.*; 009 import static hirondelle.web4j.util.Consts.FAILS; 010 import static hirondelle.web4j.util.Consts.FILE_SEPARATOR; 011 import hirondelle.web4j.util.Util; 012 013 /** 014 * Basic information on the target project. 015 */ 016 public final class BaseInfo { 017 018 /** 019 * Full constructor. 020 * 021 * @param aProjectName simple name or alias for the project, displayed as a reminder (required). 022 * @param aBaseDirectory base or root directory for your project's source files. 023 * @param aBaseURIForFetchingImages URI for running web app; when a simple image file 024 * name is concatenated with this URI, then the image will be fetched. Used for listing all image files in 025 * the target project. 026 */ 027 public BaseInfo(SafeText aProjectName, SafeText aBaseDirectory, SafeText aBaseURIForFetchingImages) throws ModelCtorException { 028 fProjecName = aProjectName; 029 fBaseDirectory = aBaseDirectory; 030 fBaseURIForFetchingImages = aBaseURIForFetchingImages; 031 validateState(); 032 } 033 034 public SafeText getProjectName() { return fProjecName; } 035 public SafeText getBaseDirectory() { return fBaseDirectory; } 036 public SafeText getBaseURIForFetchingImages() { return fBaseURIForFetchingImages; } 037 038 /** Intended for debugging only. */ 039 @Override public String toString() { 040 return ModelUtil.toStringFor(this); 041 } 042 043 @Override public boolean equals( Object aThat ) { 044 Boolean result = ModelUtil.quickEquals(this, aThat); 045 if ( result == null ){ 046 BaseInfo that = (BaseInfo) aThat; 047 result = ModelUtil.equalsFor(this.getSignificantFields(), that.getSignificantFields()); 048 } 049 return result; 050 } 051 052 @Override public int hashCode() { 053 if ( fHashCode == 0 ) { 054 fHashCode = ModelUtil.hashCodeFor(getSignificantFields()); 055 } 056 return fHashCode; 057 } 058 059 // PRIVATE // 060 private SafeText fProjecName; 061 private SafeText fBaseDirectory; 062 private SafeText fBaseURIForFetchingImages; 063 private int fHashCode; 064 065 private void validateState() throws ModelCtorException { 066 ModelCtorException ex = new ModelCtorException(); 067 if( FAILS == Check.required(fProjecName) ) { 068 ex.add("Project Name is required."); 069 } 070 if ( FAILS == Check.required(fBaseDirectory, validDirectory())) { 071 ex.add("Base Directory is required: an existing, read-able directory, ending with a " + Util.quote(FILE_SEPARATOR) + "."); 072 } 073 if ( ex.isNotEmpty() ) throw ex; 074 } 075 076 private Validator validDirectory() { 077 return new Validator() { 078 public boolean isValid(Object aObject) { 079 SafeText text = (SafeText)aObject; 080 File file = new File(text.getRawString()); 081 return file.isDirectory() && file.exists() && file.canRead() && file.isAbsolute() && endsWithSeparator(text); 082 } 083 }; 084 } 085 086 private boolean endsWithSeparator(SafeText aDir){ 087 return aDir.getRawString().endsWith(FILE_SEPARATOR); 088 } 089 090 private Object[] getSignificantFields(){ 091 return new Object[] {fProjecName, fBaseDirectory, fBaseURIForFetchingImages}; 092 } 093 }