1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.ginp.setup;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.StringReader;
29 import java.io.UnsupportedEncodingException;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32 import java.util.ArrayList;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.prefs.BackingStoreException;
36 import java.util.prefs.Preferences;
37
38 import javax.xml.transform.TransformerException;
39
40 import net.sf.ginp.setup.data.DirectoryPref;
41 import net.sf.ginp.setup.data.SetupVisit;
42 import net.sf.ginp.util.GinpUtil;
43 import net.sf.ginp.config.Configuration;
44
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47 import org.dom4j.Document;
48 import org.dom4j.DocumentException;
49 import org.dom4j.Element;
50 import org.dom4j.io.OutputFormat;
51 import org.dom4j.io.SAXReader;
52 import org.dom4j.io.XMLWriter;
53 import org.dom4j.tree.DefaultDocumentType;
54 import org.xml.sax.InputSource;
55
56 import com.thoughtworks.xstream.XStream;
57
58 /**
59 * Implementation of Setup Manager
60 * @author Justin Sher
61 * @see net.sf.ginp.setup.SetupManager
62 **/
63 public class SetupManagerImpl implements SetupManager {
64 private Log log = LogFactory.getLog(SetupManagerImpl.class);
65 private static final String TROUBLE_PARSING = "troubleParsing";
66 /**
67 * @param configUrl the URL identifying the config to check
68 * @return true or false
69 * @see net.sf.ginp.setup.SetupManager#configExists(URL configUrl)
70 */
71 public boolean configExists(URL configUrl) {
72
73
74 File fileTest = new File(GinpUtil.getConfigFileRealPath());
75 if (!fileTest.canRead()) {
76 return false;
77 }
78 return true;
79 }
80
81 /**
82 * @see net.sf.ginp.setup.SetupManager#deleteConfiguration(java.net.URL)
83 */
84 public void deleteConfiguration(URL configUrl) {
85 Preferences preferences = Preferences.userNodeForPackage(SetupManagerImpl.class);
86 preferences.remove(configUrl.toExternalForm());
87 try {
88 preferences.flush();
89 } catch (BackingStoreException e) {
90 log.error("No big deal if we couldn't delete", e);
91 }
92 }
93
94 /**
95 * @throws SetupException
96 * @see net.sf.ginp.setup.SetupManager#createConfiguration(java.net.URL, java.lang.String)
97 */
98 public void createConfiguration(URL configUrl, String configuration) throws SetupException {
99 storeConfig(configUrl, configuration);
100 }
101
102 /**
103 * @param configUrl
104 * @param configuration
105 * @return the saves prefs object
106 */
107 private Preferences storeConfig(URL configUrl, String configuration) {
108 Preferences preferences = Preferences.userNodeForPackage(SetupManagerImpl.class);
109 preferences.put(configUrl.toExternalForm(),configuration);
110 return preferences;
111 }
112
113 /**
114 * @see net.sf.ginp.setup.SetupManager#validConfigLoc(java.lang.String)
115 */
116 public Boolean validConfigLoc(String path) {
117 File pathDir=new File(path);
118 if (!pathDir.isDirectory()) { return new Boolean(false); }
119 if (!pathDir.canWrite()) { return new Boolean(false); }
120 if (!pathDir.canRead()) { return new Boolean(false);}
121 return new Boolean(true);
122 }
123
124 /**
125 * @throws SetupException if there's a problem reading the doc
126 * note: don't be fooled, we can't report the path of the
127 * offending document because it is supplied as a Stream.
128 * @throws IOException
129 * @see net.sf.ginp.setup.SetupManager#testValidConfig(java.io.InputStream)
130 */
131 public Document testValidConfig(InputStream stream) throws SetupException, IOException {
132 String reader = GinpUtil.readBufferIntoMemory(stream);
133 try {
134 return validateConfig(new ByteArrayInputStream(reader.getBytes()));
135 }
136 catch (DocumentException d) {
137 SAXReader read=new SAXReader(false);
138 try {
139 InputSource source=new InputSource();
140 source.setCharacterStream(new StringReader(reader));
141 String ginpFile=this.getClass().getResource("/net/sf/ginp/config/ginp.dtd").toExternalForm();
142 ginpFile=ginpFile.substring(0,ginpFile.lastIndexOf("/")+1);
143 source.setSystemId(ginpFile);
144 source.setPublicId("ginp.dtd");
145 Document document = read.read(source);
146 List list = document.selectNodes("/ginp/collection/users");
147 list.addAll(document.selectNodes("/ginp/collection/admins"));
148 Iterator iter=list.iterator();
149 while (iter.hasNext()) {
150 Element e=(Element) iter.next();
151 String value=e.getText();
152 String users[]=value.split(",");
153 for (int x=0;x<users.length;x++) {
154 if (users[x].length()==0) { continue; }
155 Element element = e.addElement("username");
156 element.setText(users[x].trim());
157 }
158 e.setText("");
159 }
160 try {
161 return validateConfig(new ByteArrayInputStream(document.asXML().getBytes()));
162 }
163 catch (DocumentException e) {
164
165 if (e.getMessage().indexOf("not supported")>=0) {
166 log.warn("Validation Not Supported by your XML parser",e);
167 return document;
168 } else {
169 log.error("Validation Error:", e);
170 }
171 throw e;
172 }
173 } catch (DocumentException e) {
174 log.error("throwing new SetupException", e);
175 throw new SetupException(GinpUtil.message(TROUBLE_PARSING),d);
176 }
177 }
178
179 }
180
181 /**
182 * @param stream
183 * @return
184 * @throws IOException
185 * @throws DocumentException
186 */
187 private Document validateConfig(InputStream stream) throws IOException, DocumentException {
188 SAXReader read=new SAXReader(true);
189 InputSource source=new InputSource();
190 StringReader stringRead = new StringReader(GinpUtil.readBufferIntoMemory(stream));
191 String ginpFile=this.getClass().getResource("/net/sf/ginp/config/ginp.dtd").toExternalForm();
192 ginpFile=ginpFile.substring(0,ginpFile.lastIndexOf("/")+1);
193 source.setSystemId(ginpFile);
194 source.setPublicId("ginp.dtd");
195 source.setCharacterStream(stringRead);
196 return read.read(source);
197 }
198
199 /**
200 * @see net.sf.ginp.setup.SetupManager#validPicturesLoc(java.lang.String)
201 */
202 public Boolean validPicturesLoc(String path) {
203 File pathDir=new File(path);
204 if (!pathDir.isDirectory()) { return new Boolean(false); }
205 if (!pathDir.canWrite()) { return new Boolean(false); }
206 if (!pathDir.canRead()) { return new Boolean(false);}
207 return new Boolean(true);
208 }
209
210 /**
211 * @throws SetupException
212 * @see net.sf.ginp.setup.SetupManager#writeConfigFromVisit(net.sf.ginp.setup.data.SetupVisit)
213 */
214 public Document writeConfigFromVisit(SetupVisit visit) throws SetupException {
215 try {
216 Document outputDocument = getConfigFromSetupVisit(visit);
217
218 if (!writeConfig(visit, outputDocument)){
219 log.warn("Config not written.");
220 }
221
222 return outputDocument;
223 }
224 catch (Exception e){
225 throw new SetupException(e);
226 }
227 }
228
229 /**
230 * @param visit
231 * @param outputDocument
232 * @throws FileNotFoundException
233 * @throws UnsupportedEncodingException
234 * @throws IOException
235 */
236 public boolean writeConfig(SetupVisit visit, Document outputDocument) throws FileNotFoundException, UnsupportedEncodingException, IOException {
237 FileOutputStream outputStream = null;
238 XMLWriter write = null;
239 boolean success = false;
240 try {
241 String confFileLocation = Configuration.getConfigfilelocation();
242 if (confFileLocation == null) {
243 log.warn("Configuration.getConfigfilelocation() is NULL!");
244 }
245
246
247 File configDir = new File(Configuration.getConfigfilelocationPath());
248 if(!configDir.exists()) {
249 if (configDir.mkdirs()){
250 log.info("Config directory created at: "
251 + configDir.getAbsolutePath());
252 } else {
253 log.error("Can not create config directory at: "
254 + configDir.getAbsolutePath());
255 }
256 } else {
257 if (log.isDebugEnabled()) {
258 log.debug("Config dir exists at:" + configDir.getAbsolutePath());
259 }
260 }
261
262 File configFile = new File(confFileLocation);
263 if (configFile.exists()) {
264 log.warn("Overwriting config file at: " + configFile.getAbsolutePath());
265 }
266
267 outputStream = new FileOutputStream(configFile, false);
268 OutputFormat format=OutputFormat.createPrettyPrint();
269 write=new XMLWriter(outputStream,format);
270 write.write(outputDocument);
271 success = configFile.exists();
272 } catch (Exception ex) {
273 log.error("Error writing config.", ex);
274 } finally {
275 if (write!=null) {
276 write.flush();
277 write.close();
278 }
279 if (outputStream!=null) {
280 outputStream.flush();
281 outputStream.close();
282 }
283 }
284 return success;
285 }
286
287 /**
288 * @param visit
289 * @return
290 * @throws DocumentException
291 * @throws TransformerException
292 */
293 private Document getConfigFromSetupVisit(SetupVisit visit) throws DocumentException, TransformerException {
294 XStream stream=new XStream();
295 String visitXML= stream.toXML(visit);
296 SAXReader read=new SAXReader();
297 Document visitDoc = read.read(new StringReader(visitXML));
298 Document outputDocument = GinpUtil.transform("/net/sf/ginp/setup/visitToConfig.xsl",visitDoc);
299
300 outputDocument.setDocType(new DefaultDocumentType("ginp","-//GINP//DTD ginp XML//EN","ginp.dtd"));
301 return outputDocument;
302 }
303
304 /**
305 * @throws TransformerException
306 * @throws DocumentException
307 * @see net.sf.ginp.setup.SetupManager#finalPageTransform(net.sf.ginp.setup.data.SetupVisit)
308 */
309 public String finalPageTransform(SetupVisit config) throws TransformerException, DocumentException {
310 XStream stream=new XStream();
311 String visitXML= stream.toXML(config);
312 SAXReader reader=new SAXReader();
313 Document setupDoc=reader.read(new StringReader(visitXML));
314 Document i18nDoc = reader.read(this.getClass().getResourceAsStream("/net/sf/ginp/setup/"+GinpUtil.message("finalPageI18n").trim()));
315 setupDoc.getRootElement().add(i18nDoc.getRootElement());
316 Document htmlOut = GinpUtil.transform("/net/sf/ginp/setup/finalPage.xsl",setupDoc);
317 return htmlOut.asXML();
318 }
319
320
321 /**
322 * @see net.sf.ginp.setup.SetupManager#getCommandLineForSetupVisit(net.sf.ginp.setup.data.SetupVisit)
323 */
324 public String getCommandLineForSetupVisit(SetupVisit visit) {
325
326 String javaCommand="--url "+visit.getSetupURL()+" --config-path "+
327 Configuration.getConfigfilelocation() +" --photo-path "+visit.getGinpPhotosPath()+" --admin-password "+
328 visit.getAdminPassword()+" --guest-password "+visit.getGuestPassword();
329 Iterator iterator = visit.getDirectoryPrefs().iterator();
330 while (iterator.hasNext()) {
331 DirectoryPref dirPref=(DirectoryPref) iterator.next();
332 if (dirPref.getType().equals(DirectoryPref.ADMIN_ONLY)) {
333 javaCommand+=" --admin "+dirPref.getRootDir();
334 }
335 else if (dirPref.getType().equals(DirectoryPref.PUBLIC)) {
336 javaCommand+=" --public "+dirPref.getRootDir();
337 }
338 else if (dirPref.getType().equals(DirectoryPref.PRIVATE)) {
339 javaCommand+=" --private "+dirPref.getRootDir();
340 }
341 }
342 return javaCommand;
343 }
344
345 /**
346 * @see net.sf.ginp.setup.SetupManager#getSetupVisitForCommandLine(java.lang.String[])
347 */
348 public SetupVisit getSetupVisitForCommandLine(String[] argv) throws DocumentException, TransformerException {
349 SetupVisit visit=new SetupVisit();
350 for(int x=0;x<argv.length;x++) {
351 String command=argv[x];
352 if (command.equals("--url")) {
353 visit.setSetupURL(argv[x++]);
354 }
355 else if (command.equals("--photo-path")) {
356 visit.setGinpPhotosPath(argv[x++]);
357 }
358 else if (command.equals("--admin-password")) {
359 visit.setAdminPassword(argv[x++]);
360 }
361 else if (command.equals("--guest-password")) {
362 visit.setGuestPassword(argv[x++]);
363 }
364 else if (command.equals("--private")) {
365 DirectoryPref privDir=new DirectoryPref();
366 privDir.setRootDir(privDir.getName());
367 privDir.setType(DirectoryPref.PRIVATE);
368 privDir.setUserVariables();
369 visit.addCollection(privDir);
370 }
371 else if (command.equals("--admin")) {
372 DirectoryPref privDir=new DirectoryPref();
373 privDir.setRootDir(privDir.getName());
374 privDir.setType(DirectoryPref.ADMIN_ONLY);
375 privDir.setUserVariables();
376 visit.addCollection(privDir);
377 }
378 else if (command.equals("--public")) {
379 DirectoryPref privDir=new DirectoryPref();
380 privDir.setRootDir(privDir.getName());
381 privDir.setType(DirectoryPref.PUBLIC);
382 privDir.setUserVariables();
383 visit.addCollection(privDir);
384 }
385 }
386
387 this.getConfigFromSetupVisit(visit);
388 return visit;
389 }
390
391 /**
392 * @param sampleConfig
393 * @return
394 * @see net.sf.ginp.setup.SetupManager#getDirectoriesInPictureDirectory(net.sf.ginp.setup.data.SetupVisit)
395 */
396 public List getDirectoriesInPictureDirectory(SetupVisit sampleConfig) {
397 File dir=new File(sampleConfig.getGinpPhotosPath());
398 String[] strings = dir.list();
399 ArrayList directories = new ArrayList();
400 for(int x=0;x<strings.length;x++) {
401 String path=sampleConfig.getGinpPhotosPath()+System.getProperty("file.separator")+strings[x];
402 File file = new File(path);
403 if (!file.exists()) {
404 path=sampleConfig.getGinpPhotosPath()+strings[x];
405 file = new File(path);
406 }
407 if (file.canRead() && file.canWrite() && file.isDirectory()) {
408 directories.add(file);
409 }
410 }
411 return directories;
412 }
413
414 /**
415 * Sets the configuration in the preferences from the visit's path and url
416 * @throws SetupException
417 * @throws MalformedURLException
418 * @see net.sf.ginp.setup.SetupManager#setConfiguration(net.sf.ginp.setup.data.SetupVisit)
419 */
420 public void setConfiguration(SetupVisit visit) throws MalformedURLException, SetupException {
421 String uri=visit.getSetupURL();
422 uri=uri.substring(0,uri.lastIndexOf('/'));
423 deleteConfiguration(new URL(uri));
424 createConfiguration(new URL(uri),Configuration.getConfigfilelocation());
425 }
426
427
428 }