KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > projector > application > ApplicationManager


1 package org.apache.slide.projector.application;
2
3 import java.io.IOException JavaDoc;
4 import java.io.InputStream JavaDoc;
5 import java.util.ArrayList JavaDoc;
6 import java.util.Collection JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.List JavaDoc;
10 import java.util.Map JavaDoc;
11 import java.util.logging.Level JavaDoc;
12 import java.util.logging.Logger JavaDoc;
13
14 import javax.xml.parsers.ParserConfigurationException JavaDoc;
15
16 import org.apache.slide.projector.Context;
17 import org.apache.slide.projector.Projector;
18 import org.apache.slide.projector.SystemContext;
19 import org.apache.slide.projector.URI;
20 import org.apache.slide.projector.descriptor.ValueFactory;
21 import org.apache.slide.projector.descriptor.ValueFactoryManager;
22 import org.apache.slide.projector.engine.ProcessorManager;
23 import org.apache.slide.projector.engine.ProjectorClassLoader;
24 import org.apache.slide.projector.engine.Scheduler;
25 import org.apache.slide.projector.i18n.MessageManager;
26 import org.apache.slide.projector.value.ArrayValue;
27 import org.apache.slide.projector.value.StreamableValue;
28 import org.apache.slide.projector.value.URIValue;
29 import org.apache.slide.projector.value.Value;
30 import org.apache.webdav.lib.Subscriber;
31 import org.xml.sax.InputSource JavaDoc;
32 import org.xml.sax.SAXException JavaDoc;
33 import org.xml.sax.helpers.AttributesImpl JavaDoc;
34
35 import de.zeigermann.xml.simpleImporter.DefaultSimpleImportHandler;
36 import de.zeigermann.xml.simpleImporter.SimpleImporter;
37 import de.zeigermann.xml.simpleImporter.SimplePath;
38
39 public class ApplicationManager {
40     private final static Logger JavaDoc logger = Logger.getLogger(ApplicationManager.class.getName());
41
42     private final static String JavaDoc APPLICATION_CONFIG = "application.xml";
43     private final static Context context = new SystemContext();
44     private final static String JavaDoc CLASSES_DIR = "classes/";
45
46     private static ApplicationManager applicationManager;
47     private List JavaDoc applicationListeners = new ArrayList JavaDoc();
48     private Map JavaDoc installedApplications = new HashMap JavaDoc(); // URI -> Application
49
// FIXME: Should be used from applications classpath
50
private ProjectorClassLoader factoryClassLoader = new ProjectorClassLoader(this.getClass().getClassLoader(), new URIValue(Projector.getProjectorDir()+CLASSES_DIR));
51     
52     private ApplicationManager() {
53         logger.log(Level.INFO, "Starting application manager");
54         Projector.getRepository().subscribe("Update/newmember", new URIValue(Projector.getApplicationsDir()), 1,
55                 new Subscriber() {
56             public void notify(String JavaDoc uri, Map JavaDoc information) {
57                 logger.log(Level.FINE, "Package manager received add event");
58                 applicationManager.installApplications();
59             }
60         }, context.getCredentials());
61         Projector.getRepository().subscribe("Delete", new URIValue(Projector.getApplicationsDir()), 1,
62                 new Subscriber() {
63             public void notify(String JavaDoc uri, Map JavaDoc information) {
64                 logger.log(Level.FINE, "Package manager received delete event");
65                 applicationManager.installApplications();
66             }
67         }, context.getCredentials());
68         applicationListeners.add(ProcessorManager.getInstance());
69         applicationListeners.add(MessageManager.getInstance());
70         applicationListeners.add(Scheduler.getInstance());
71         installApplications();
72     }
73
74     private synchronized void installApplications() {
75         Value[] applicationUris;
76         List JavaDoc applicationsToInstall = new ArrayList JavaDoc();
77         List JavaDoc applicationsToRemove = new ArrayList JavaDoc();
78         try {
79             List JavaDoc removedApplications = new ArrayList JavaDoc();
80             removedApplications.addAll(installedApplications.keySet());
81             applicationUris = ((ArrayValue)Projector.getRepository().getChildren(new URIValue(Projector.getApplicationsDir()), context.getCredentials())).getArray();
82             for ( int i = 0; i < applicationUris.length; i++ ) {
83                 String JavaDoc applicationUri = applicationUris[i].toString();
84                 if ( !applicationUri.endsWith("/") ) {
85                     applicationUri = applicationUri + "/";
86                 }
87                 /* FIXME: Is this needed or can it be fixed in getChildren() ?
88                 if ( applicationUri.indexOf(Constants.REPOSITORY_DOMAIN) != -1 ) {
89                     applicationUri = applicationUri.substring(applicationUri.indexOf(Constants.REPOSITORY_DOMAIN)+Constants.REPOSITORY_DOMAIN.length());
90                 }
91                 */

92                 if ( !installedApplications.containsKey(applicationUri) ) {
93                     Application installedApplication = parseApplication(new URIValue(applicationUri));
94                     if ( installedApplication != null ) {
95                         applicationsToInstall.add(installedApplication);
96                     }
97                 } else {
98                     logger.log(Level.FINE, "Application '"+applicationUri+"' already installed");
99                     removedApplications.remove(applicationUri);
100                 }
101             }
102             for ( Iterator JavaDoc i = removedApplications.iterator(); i.hasNext(); ) {
103                 Application removedApplication = (Application)installedApplications.get((URI)i.next());
104                 applicationsToRemove.add(removedApplication);
105             }
106             // install applications sorted by application dependencies
107
List JavaDoc sortedApplications = sortApplications(applicationsToInstall);
108             for ( Iterator JavaDoc i = sortedApplications.iterator(); i.hasNext(); ) {
109                 Application application = (Application)i.next();
110                 Projector.getRepository().subscribe("Update", application.getUri(), 0,
111                         new Subscriber() {
112                     public void notify(String JavaDoc uri, Map JavaDoc information) {
113                         applicationManager.updateApplication(uri);
114                     }
115                 }, context.getCredentials());
116                 install(Application.MESSAGES, application);
117                 install(Application.PROCESSORS, application);
118             }
119             Scheduler.getInstance().install(new URIValue(Projector.getWorkDir() + Scheduler.JOBS), true);
120             for ( Iterator JavaDoc i = sortedApplications.iterator(); i.hasNext(); ) {
121                 Application application = (Application)i.next();
122                 install(Application.JOBS, application);
123             }
124             Scheduler.getInstance().saveJobs();
125         } catch (IOException JavaDoc e) {
126             logger.log(Level.SEVERE, "Could not determine installed applications!", e);
127         }
128     }
129     
130     public static ApplicationManager getInstance() {
131         if ( applicationManager == null ) {
132             applicationManager = new ApplicationManager();
133         }
134         return applicationManager;
135     }
136     
137     private List JavaDoc sortApplications(List JavaDoc applicationsToInstall) {
138         List JavaDoc sortedApplications = new ArrayList JavaDoc();
139         for ( Iterator JavaDoc i = applicationsToInstall.iterator(); i.hasNext(); ) {
140             Application application = (Application)i.next();
141             if ( !sortedApplications.contains(application) ) {
142                 logger.log(Level.FINE, "Try to install '"+application.getName()+"'");
143                 addRequiredApplicationsFirst(sortedApplications, applicationsToInstall, application);
144             }
145         }
146         return sortedApplications;
147     }
148
149     private void addRequiredApplicationsFirst(List JavaDoc sortedApplications, List JavaDoc applicationsToInstall, Application application) {
150         // FIXME: Check application versions
151
logger.log(Level.FINE, "Checking for dependencies...");
152         for ( Iterator JavaDoc i = application.getDependencies().iterator(); i.hasNext(); ) {
153             Dependency dependency = (Dependency)i.next();
154             logger.log(Level.FINE, "Dependency on application '"+dependency.getRequiredApplication()+"' found!");
155             Application requiredApplication = getApplicationByName(applicationsToInstall, dependency.getRequiredApplication());
156             if ( requiredApplication == null ) {
157                 // check if application is already installed
158
requiredApplication = getApplicationByName(installedApplications.entrySet(), dependency.getRequiredApplication());
159                 if ( requiredApplication == null ) {
160                     // FIXME: Throw exception and abort startup
161
logger.log(Level.SEVERE, "Required application '"+dependency.getRequiredApplication()+"' not found!");
162                 }
163             } else {
164                 logger.log(Level.FINE, "Required application '"+requiredApplication.getName()+"' not installed but available, so install it first");
165                 addRequiredApplicationsFirst(sortedApplications, applicationsToInstall, requiredApplication);
166             }
167         }
168         if ( !sortedApplications.contains(application) ) {
169             logger.log(Level.FINE, "Adding '"+application.getName()+"' to installation process");
170             sortedApplications.add(application);
171         }
172     }
173     
174     private Application getApplicationByName(Collection JavaDoc applications, String JavaDoc name) {
175         for ( Iterator JavaDoc i = applications.iterator(); i.hasNext(); ) {
176             Application application = (Application)i.next();
177             if ( application.getName().equals(name)) {
178                 return application;
179             }
180         }
181         return null;
182     }
183     
184     private Application parseApplication(URI applicationUri) {
185         try {
186             SimpleImporter importer = new SimpleImporter();
187             URI applicationDefinition = new URIValue(applicationUri.toString()+APPLICATION_CONFIG);
188             StreamableValue applicationDefinitionResouce = ((StreamableValue)Projector.getRepository().getResource(applicationDefinition, context.getCredentials()));
189             if ( applicationDefinitionResouce != null ) {
190                 InputStream JavaDoc configuration = applicationDefinitionResouce.getInputStream();
191                 ConfigurationHandler handler = new ConfigurationHandler(applicationUri);
192                 importer.addSimpleImportHandler(handler);
193                 importer.parse(new InputSource JavaDoc(configuration));
194                 return handler.getApplication();
195             } else {
196                 logger.log(Level.SEVERE, "Application definition (application.xml) not found in directory '"+applicationUri+"'. Application will not be installed!");
197             }
198         } catch (ParserConfigurationException JavaDoc e) {
199             logger.log(Level.SEVERE, "Exception while parsing application configuration. Skipping installation...", e);
200         } catch (SAXException JavaDoc e) {
201             logger.log(Level.SEVERE, "Exception while parsing application configuration. Skipping installation...", e);
202         } catch (IOException JavaDoc e) {
203             logger.log(Level.SEVERE, "Could not get application information. Skipping installation...", e);
204         }
205         return null;
206     }
207     
208     private Application getApplication(List JavaDoc applications, URI applicationUri) {
209         for ( Iterator JavaDoc i = applications.iterator(); i.hasNext(); ) {
210             Application application = (Application)i.next();
211             if ( application.getUri().equals(applicationUri) ) return application;
212         }
213         return null;
214     }
215     
216     private synchronized void updateApplication(String JavaDoc uri) {
217         URI applicationUri = new URIValue(uri);
218         logger.log(Level.FINE, "Updating application '"+applicationUri+"'");
219         // Compare newly parsed application with previously installed and send diffs
220
Application installedApplication = (Application)installedApplications.get(applicationUri);
221         Application updatedApplication = parseApplication(applicationUri);
222         for ( Iterator JavaDoc i = installedApplication.getContent().entrySet().iterator(); i.hasNext(); ) {
223             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
224             List JavaDoc removed = new ArrayList JavaDoc();
225             removed.addAll((List JavaDoc)entry.getValue());
226             List JavaDoc updated = updatedApplication.getContent((String JavaDoc)entry.getKey());
227             if ( updated != null ) {
228                 removed.removeAll(updated);
229             }
230             for ( Iterator JavaDoc j = removed.iterator(); j.hasNext(); ) {
231                 for ( Iterator JavaDoc k = applicationListeners.iterator(); k.hasNext(); ) {
232                     ((ApplicationListener)k.next()).uninstall((String JavaDoc)entry.getKey(), updatedApplication.getUri(), (URI)j.next());
233                 }
234             }
235         }
236         for ( Iterator JavaDoc i = updatedApplication.getContent().entrySet().iterator(); i.hasNext(); ) {
237             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
238             List JavaDoc added = new ArrayList JavaDoc();
239             added.addAll((List JavaDoc)entry.getValue());
240             List JavaDoc installed = installedApplication.getContent((String JavaDoc)entry.getKey());
241             if ( installed != null ) {
242                 added.removeAll(installed);
243             }
244             for ( Iterator JavaDoc j = added.iterator(); j.hasNext(); ) {
245                 for ( Iterator JavaDoc k = applicationListeners.iterator(); k.hasNext(); ) {
246                     ((ApplicationListener)k.next()).install((String JavaDoc)entry.getKey(), updatedApplication.getUri(), (URI)j.next());
247                 }
248             }
249         }
250     }
251
252     private void install(String JavaDoc type, Application application) {
253         logger.log(Level.FINE, "Installing "+type+" of application '"+application.getUri()+"'");
254         List JavaDoc contents = (List JavaDoc)application.getContent().get(type);
255         if ( contents != null ) {
256             for ( Iterator JavaDoc j = contents.iterator(); j.hasNext(); ) {
257                 URI uri = (URI)j.next();
258                 for ( Iterator JavaDoc k = applicationListeners.iterator(); k.hasNext(); ) {
259                     ((ApplicationListener)k.next()).install(type, application.getUri(), uri);
260                 }
261             }
262         }
263         installedApplications.put(application.getUri(), application);
264     }
265     
266     private void uninstall(String JavaDoc type, Application application) {
267         logger.log(Level.FINE, "Uninstall "+type+" of application '"+application.getUri()+"'");
268         for ( Iterator JavaDoc i = application.getContent().entrySet().iterator(); i.hasNext(); ) {
269             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
270             for ( Iterator JavaDoc j = ((List JavaDoc)entry.getValue()).iterator(); j.hasNext(); ) {
271                 URI uri = (URI)j.next();
272                 for ( Iterator JavaDoc k = applicationListeners.iterator(); k.hasNext(); ) {
273                     ((ApplicationListener)k.next()).uninstall((String JavaDoc)entry.getKey(), application.getUri(), uri);
274                 }
275             }
276         }
277         // FIXME: Remove subscriber
278
installedApplications.remove(application.getUri());
279     }
280     
281     private final class ConfigurationHandler extends DefaultSimpleImportHandler {
282         private Application application;
283         private URI applicationUri;
284         
285         private ConfigurationHandler(URI applicationUri) {
286             this.applicationUri = applicationUri;
287         }
288
289         private Application getApplication() {
290             return application;
291         }
292         
293         public void startElement(SimplePath path, String JavaDoc name, AttributesImpl JavaDoc attributes, String JavaDoc leadingCDdata) {
294             if (path.matches("application")) {
295                 application = new Application(applicationUri);
296             } else if ( path.matches("application/name") ) {
297                 application.setName(leadingCDdata);
298             } else if ( path.matches("application/display-name") ) {
299                 application.setDisplayName(leadingCDdata);
300             } else if ( path.matches("application/vendor") ) {
301                 application.setVendor(leadingCDdata);
302             } else if ( path.matches("application/description") ) {
303                 application.setDescription(leadingCDdata);
304             } else if ( path.matches("application/version") ) {
305                 application.setVersion(leadingCDdata);
306             } else if ( path.matches("application/dependencies/requires") ) {
307                 Dependency dependency = new Dependency(attributes.getValue("application"), attributes.getValue("version"));
308                 application.addDependency(dependency);
309             } else if ( path.matches("application/resource-types/resource-type") ) {
310                 String JavaDoc resourceTypeName = attributes.getValue("name");
311                 String JavaDoc clazz = attributes.getValue("class");
312                 try {
313                     ValueFactory descriptorFactory = (ValueFactory)factoryClassLoader.loadClass(clazz).getConstructor(new Class JavaDoc[0]).newInstance(new Object JavaDoc[0]);
314                     ValueFactoryManager.getInstance().registerDescriptorFactory(descriptorFactory);
315                     logger.log(Level.FINE, "Successfully registered descriptor factory " + clazz);
316                 } catch (Exception JavaDoc e) {
317                     logger.log(Level.SEVERE, "Descriptor factory " + clazz + " could not loaded!", e);
318                 }
319             } else if ( path.matches("application/content/processors") ) {
320                 String JavaDoc uri = attributes.getValue("uri");
321                 application.addContent(Application.PROCESSORS, new URIValue(applicationUri+attributes.getValue("uri")));
322             } else if ( path.matches("application/content/messages") ) {
323                 application.addContent(Application.MESSAGES, new URIValue(applicationUri+attributes.getValue("uri")));
324             } else if ( path.matches("application/content/jobs") ) {
325                 application.addContent(Application.JOBS, new URIValue(applicationUri+attributes.getValue("uri")));
326             }
327         }
328     }
329 }
Popular Tags