View Javadoc
1   /******************************************************************************
2    * NewPicScannerImpl.java - Implement the Scan for new pictures interface
3    * 
4    * PicMan - The BuckoSoft Picture Manager in Java
5    * Copyright(c) 2005 - Dick Balaska
6    * 
7    */
8   package com.buckosoft.PicMan.business;
9   
10  import java.awt.Dimension;
11  import java.io.File;
12  import java.util.ArrayList;
13  import java.util.Date;
14  import java.util.HashMap;
15  import java.util.Iterator;
16  import java.util.LinkedList;
17  import java.util.List;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  
22  import com.buckosoft.PicMan.business.util.MD5SumUpdater;
23  import com.buckosoft.PicMan.domain.Pic;
24  import com.buckosoft.PicMan.domain.Root;
25  
26  /** Implement the Scan For New Pictures Interface. <br>
27   * Scan the Root directories looking for pictures that haven't been catalogued.
28   * Add any found pics to the database and create a virgin entry.
29   * @author Dick Balaska
30   * @since 2005/07/28
31   */
32  public class NewPicScannerImpl implements NewPicScanner {
33  	
34  	protected final Log logger = LogFactory.getLog(getClass());
35  	private static final boolean DEBUG = false;
36  	
37  	private	LinkedList<String>	picExtensions;
38  	private	Root				currentRoot;
39  	private	ArrayList<File>		newPics;
40  	private	PicManFacade		pmf;
41  	private	String				processErrorMessage = "";
42  	private	HashMap<String, Date>				existingPicsMap;
43  	
44  	public NewPicScannerImpl(){
45  		newPics = new ArrayList<File>();
46  	}
47  	
48  	/** Constructor that sets the reference to PicManFacade
49  	 * @param pmf The PicManFacade primary interface
50  	 */
51  	public NewPicScannerImpl(PicManFacade pmf) {
52  		newPics = new ArrayList<File>();
53  		this.pmf = pmf;
54  		setPicExtensions(pmf.getDB().getPicExtensions());
55  	}
56  	/** Set the pic extensions that are known pics
57  	 * @param list A list of file extensions, typically just "jpg"
58  	 */
59  	public void setPicExtensions(List<String> list) {picExtensions = new LinkedList<String>(list); }
60  	
61  	/** Return the newPics array
62  	 * @return The list of pics that we've found after scanning
63  	 */
64  	public ArrayList<File>	getNewPics() { return(newPics); }
65  	
66  	/** Scan the root directories and build a list of pics found.
67  	 * @return The number of new pics found.
68  	 */
69  	public int getNewPicCount() throws Exception {
70  		if (DEBUG)
71  			logger.info("getNewPicCount()");
72  		
73  		int	newCount = 0;
74  		newPics.clear();
75  		Iterator<Root>	it;
76  		
77  		existingPicsMap = pmf.getDB().getPicsMap();
78  		if (DEBUG)
79  			logger.info("existingPicsMap= " + existingPicsMap.size());
80  		List<Root> roots = pmf.getDB().getRoots();
81  		it = roots.iterator();
82  		while(it.hasNext()) {
83  			currentRoot = (Root)it.next();
84  			if (currentRoot.isActive() == false)
85  				continue;
86  			File f = new File(currentRoot.getPath());
87  			newCount = processFile(f, newCount);
88  		}
89  		existingPicsMap = null;
90  		return(newCount);
91  	}
92  	
93  	private int processFile(File f, int newCount) throws Exception
94  	{
95  		if (f.isFile()) {
96  //			if (DEBUG)
97  //				logger.info("processFile() check '" + f.getName() + "'");
98  			String	s = f.getName();
99  			Iterator<String> it = picExtensions.iterator();
100 			boolean match = false;
101 			while (it.hasNext()) {
102 				if (s.endsWith((String)it.next())) {
103 					match = true;
104 					break;
105 				}
106 			}
107 			if (match) {
108 				if (picExists(f))
109 					return(newCount);
110 				newPics.add(f);
111 				newCount++;
112 			}
113 			return(newCount);
114 		}
115 		if (f.isDirectory()) {
116 			File[] files = f.listFiles();
117 			for (int i=0; i<files.length; i++)
118 				newCount = processFile(files[i], newCount);
119 			return(newCount);
120 		}
121 		throw new Exception("file '" + f.getName() + "' is neither file nor directory");
122 	}
123 	
124 	private	boolean picExists(File f) {
125 		String	s = f.getName();
126 		if (s.endsWith(".jpg")) {
127 			s = s.substring(0,s.length()-4);
128 //			logger.info("check '" + s + "' in map");
129 			if (existingPicsMap.containsKey(s))
130 				return(true);
131 		}
132 		return(false);
133 	}
134 	
135 	/** Process any pics in the newPics list.
136 	 * Add them to the Pics table and the Virgins table.
137 	 * @return success
138 	 */
139 	public boolean processNewPics() {
140 		processErrorMessage = "Broken!";
141 		Iterator<File> it = newPics.iterator();
142 		boolean success = true;
143 		List<Root>	roots = this.pmf.getDB().getRoots();
144 		File	f;
145 		String	s;
146 		Pic	pic;
147 		while (it.hasNext()) {
148 			f = (File)it.next();
149 			pic = new Pic();
150 			s = f.getName();
151 			if (s.endsWith(".jpg"))
152 				s = s.substring(0, s.length()-4);
153 			pic.setName(s);
154 			String	path = f.getParent().replace('\\', '/');
155 			Iterator<Root> riter = roots.iterator();
156 			while (riter.hasNext()) {
157 				Root root = riter.next();
158 				if (!root.isActive())
159 					continue;
160 				if (path.startsWith(root.getPath())) {
161 					pic.setRid(root.getRid());
162 					path = path.substring(root.getPath().length()+1);
163 					break;
164 				}
165 			}
166 			if (pic.getRid() == -1) {
167 				throw new RuntimeException("Can't match root for '" + pic.getName() + "' - '" + path + "'");
168 			}
169 
170 			pic.setLocation(path);
171 			pic.getDate().setTime(f.lastModified());
172 
173 			Dimension d = pmf.determinePicSize(pic);
174 			if (d.height == -1) {
175 				logger.warn("Can't determine size for pic: " + pic.getName());
176 				d.height = 0;
177 				d.width = 0;
178 			}
179 			pic.setHeight(d.height);
180 			pic.setWidth(d.width);
181 
182 			
183 			MD5SumUpdater.calculateMD5Sum(pmf, pic);
184 			pmf.getDB().addPic(pic);
185 			pmf.getDB().addVirgin(pic.getName());
186 		}
187 		return(success);
188 	}
189 
190 	/* (non-Javadoc)
191 	 * @see com.buckosoft.PicMan.business.NewPicScanner#getProcessNewPicsErrorMessage()
192 	 */
193 	public String getProcessNewPicsErrorMessage() {
194 		return(processErrorMessage);
195 	}
196 }