KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > projector > engine > ProcessorManager


1 package org.apache.slide.projector.engine;
2
3 import java.io.IOException JavaDoc;
4 import java.io.InputStream JavaDoc;
5 import java.util.ArrayList JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9 import java.util.Map JavaDoc;
10 import java.util.logging.Level JavaDoc;
11 import java.util.logging.Logger JavaDoc;
12
13 import org.apache.slide.projector.ConfigurableProcessor;
14 import org.apache.slide.projector.ConfigurationException;
15 import org.apache.slide.projector.Context;
16 import org.apache.slide.projector.EnvironmentConsumer;
17 import org.apache.slide.projector.ProcessException;
18 import org.apache.slide.projector.Processor;
19 import org.apache.slide.projector.Projector;
20 import org.apache.slide.projector.Result;
21 import org.apache.slide.projector.URI;
22 import org.apache.slide.projector.application.Application;
23 import org.apache.slide.projector.application.ApplicationListener;
24 import org.apache.slide.projector.descriptor.ParameterDescriptor;
25 import org.apache.slide.projector.descriptor.ProcessorDescriptor;
26 import org.apache.slide.projector.descriptor.ResultDescriptor;
27 import org.apache.slide.projector.descriptor.ValidationException;
28 import org.apache.slide.projector.i18n.DefaultMessage;
29 import org.apache.slide.projector.i18n.ErrorMessage;
30 import org.apache.slide.projector.processor.SimpleProcessor;
31 import org.apache.slide.projector.processor.process.Process;
32 import org.apache.slide.projector.value.AnyValue;
33 import org.apache.slide.projector.value.NullValue;
34 import org.apache.slide.projector.value.StreamableValue;
35 import org.apache.slide.projector.value.URIValue;
36 import org.apache.slide.projector.value.Value;
37 import org.apache.webdav.lib.Subscriber;
38 import org.xml.sax.InputSource JavaDoc;
39 import org.xml.sax.helpers.AttributesImpl JavaDoc;
40
41 import de.zeigermann.xml.simpleImporter.DefaultSimpleImportHandler;
42 import de.zeigermann.xml.simpleImporter.SimpleImporter;
43 import de.zeigermann.xml.simpleImporter.SimplePath;
44
45 /**
46  * The ProcessorManager is responsible for loading processors and their
47  * configuration. Because every processor is located via its URI, it might be
48  * possible to handle different versions of the same processor.
49  * They are reloaded if an event occurs that indicates, that the class or configuration has changed
50  * or was updated.
51  */

52 public class ProcessorManager implements ApplicationListener, Subscriber {
53     public final static URI BINARY = new URIValue("image");
54     public final static URI LOCALE_RESOLVER = new URIValue("localeResolver");
55     public final static URI URL = new URIValue("url");
56     public final static URI THREAD = new URIValue("thread");
57
58     private final static String JavaDoc CLASSES_DIR = "classes/";
59
60     private final static Logger JavaDoc logger = Logger.getLogger(ProcessorManager.class.getName());
61     private final static String JavaDoc PROCESSOR_CONFIG = "processors.xml";
62     private final static URI SMALL_DEFAULT_ICON = new URIValue("/files/contelligent/images/process.jpg");
63     private final static URI LARGE_DEFAULT_ICON = new URIValue("/files/contelligent/images/process.jpg");
64
65     private static ProcessorManager processorManager = new ProcessorManager();
66     
67     private Map JavaDoc configurationToApplication = new HashMap JavaDoc(); // URI -> URI
68
private Map JavaDoc installedProcessors = new HashMap JavaDoc();
69     private Map JavaDoc processorMap = new HashMap JavaDoc(256); // URI -> Processor
70
private Map JavaDoc configuredProcessors = new HashMap JavaDoc(128);
71     private Map JavaDoc configurationListeners = new HashMap JavaDoc(128);
72     private Map JavaDoc processorDescriptors = new HashMap JavaDoc(256); // URI -> ProcessorDescriptor
73
private ProjectorClassLoader processorClassLoader = new ProjectorClassLoader(this.getClass().getClassLoader(), new URIValue(Projector.getProjectorDir()+CLASSES_DIR));
74     
75     private ProcessorManager() {
76     }
77         
78     public void install(String JavaDoc type, URI applicationUri, URI configurationUri) {
79         if ( type == Application.PROCESSORS ) {
80             install(applicationUri, configurationUri);
81             configurationToApplication.put(configurationUri, applicationUri);
82         }
83     }
84     
85     public void uninstall(String JavaDoc type, URI applicationUri, URI configurationUri) {
86         if ( type == Application.PROCESSORS ) {
87             uninstall(applicationUri, configurationUri);
88             configurationToApplication.remove(configurationUri);
89         }
90     }
91     
92     public void update(String JavaDoc type, URI applcationUri, URI configurationUri) {
93         if ( type == Application.PROCESSORS ) {
94             update(applcationUri, configurationUri);
95         }
96     }
97     
98     private void install(URI applicationUri, URI configurationUri) {
99         logger.log(Level.FINE, "Installing processors '"+configurationUri+"'");
100         try {
101             InputStream JavaDoc configuration = ((StreamableValue)Projector.getRepository().getResource(configurationUri, Projector.getCredentials())).getInputStream();
102             SimpleImporter importer = new SimpleImporter();
103             List JavaDoc alreadyInstalledProcessors = (List JavaDoc)installedProcessors.get(configurationUri);
104             if ( alreadyInstalledProcessors == null ) alreadyInstalledProcessors = new ArrayList JavaDoc();
105             ConfigurationHandler handler = new ConfigurationHandler(applicationUri, alreadyInstalledProcessors);
106             importer.addSimpleImportHandler(handler);
107             importer.parse(new InputSource JavaDoc(configuration));
108             List JavaDoc removedProcessors = new ArrayList JavaDoc();
109             alreadyInstalledProcessors.addAll(handler.getAddedProcessors());
110             for ( Iterator JavaDoc i = handler.getRemovedProcessors().iterator(); i.hasNext(); ) {
111                 URI removedProcessorUri = (URI)i.next();
112                 uninstallProcessor(removedProcessorUri);
113                 alreadyInstalledProcessors.remove(removedProcessorUri);
114             }
115             installedProcessors.put(configurationUri, alreadyInstalledProcessors);
116             Projector.getRepository().subscribe("Update", configurationUri, 0, this, Projector.getCredentials());
117         } catch (Exception JavaDoc exception) {
118             logger.log(Level.SEVERE, "Error while parsing configuration", exception);
119         }
120     }
121
122     public void uninstall(URI applicationUri, URI configurationUri) {
123         logger.log(Level.FINE, "Uninstalling processors '"+configurationUri+"'");
124         List JavaDoc processors = (List JavaDoc)installedProcessors.get(configurationUri);
125         for ( Iterator JavaDoc j = processors.iterator(); j.hasNext(); ) {
126             URI processorUri = (URI)j.next();
127             uninstallProcessor(processorUri);
128         }
129         installedProcessors.remove(configurationUri);
130         Projector.getRepository().unsubscribe(configurationUri, this, Projector.getCredentials());
131     }
132     
133     private void uninstallProcessor(URI processorUri) {
134         processorMap.remove(processorUri);
135         ProcessorDescriptor processorDescriptor = getProcessorDescriptor(processorUri);
136         URI processorConfiguration = processorDescriptor.getConfiguration();
137         if ( processorConfiguration != null ) {
138             configuredProcessors.remove(processorConfiguration);
139             Subscriber subscriber = (Subscriber)configurationListeners.get(processorConfiguration);
140             Projector.getRepository().unsubscribe(processorConfiguration, subscriber, Projector.getCredentials());
141             configurationListeners.remove(processorConfiguration);
142         }
143         processorDescriptors.remove(processorUri);
144         logger.log(Level.FINE, "Removing processor: "+processorUri);
145     }
146     
147     private void update(URI applicationUri, URI configurationUri) {
148         Projector.getRepository().unsubscribe(configurationUri, this, Projector.getCredentials());
149         install(applicationUri, configurationUri);
150     }
151     
152     public static ProcessorManager getInstance() {
153         return processorManager;
154     }
155
156     public void notify(String JavaDoc uri, Map JavaDoc information) {
157         URI configurationUri = new URIValue(uri);
158         update((URI)configurationToApplication.get(configurationUri), configurationUri);
159     }
160
161     public Processor getProcessor(URI uri) throws ProcessException {
162         if ( processorMap.containsKey(uri) ) {
163             return (Processor)processorMap.get(uri);
164         }
165         logger.log(Level.SEVERE, "Requested processor with URI=" + uri+ " not found!");
166         throw new ProcessException(new ErrorMessage("processorNotFound", new Object JavaDoc[] {uri.toString()}));
167     }
168
169     public URI getURI(Processor processor) throws ProcessException {
170         for ( Iterator JavaDoc i = processorMap.entrySet().iterator(); i.hasNext(); ) {
171             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
172             if ( entry.getValue() == processor ) {
173                 return ((URI)entry.getKey());
174             }
175         }
176         logger.log(Level.SEVERE, "Requested URI for processor=" + processor + " not found!");
177         throw new ProcessException(new ErrorMessage("processorNotFound", new Object JavaDoc[] {processor.toString()}));
178     }
179
180     public Result process(URI processorUri, Map JavaDoc parameters, Context context) throws Exception JavaDoc {
181         Processor processor = getProcessor(processorUri);
182         return process(processor, parameters, context);
183     }
184     
185     public static Result process(Processor processor, Map JavaDoc parameters, Context context) throws Exception JavaDoc {
186         ParameterDescriptor[] parameterDescriptors = processor.getParameterDescriptors();
187         prepareValues(parameterDescriptors, parameters, context);
188         return processor.process(parameters, context);
189     }
190     
191     public Value process(URI simpleProcessorUri, Object JavaDoc input, Context context) throws Exception JavaDoc {
192         return process(simpleProcessorUri, input, null, context);
193     }
194
195     public Value process(URI simpleProcessorUri, Object JavaDoc input, String JavaDoc resultKey, Context context) throws Exception JavaDoc {
196         Processor processor = getProcessor(simpleProcessorUri);
197         ParameterDescriptor[] parameterDescriptors = processor.getParameterDescriptors();
198         if ( parameterDescriptors.length > 1 && countRequiredParameters(parameterDescriptors) > 1 ) {
199             throw new ProcessException(new ErrorMessage("valueProcessorNeedsTooManyParametersException"));
200         }
201         if ( resultKey == null ) {
202             ResultDescriptor resultDescriptor = processor.getResultDescriptor();
203             if ( resultDescriptor.getResultEntryDescriptors().length == 0 ) {
204                 throw new ProcessException(new ErrorMessage("parameterProcessingException", new String JavaDoc[] { simpleProcessorUri.toString() }));
205             } else {
206                 resultKey = resultDescriptor.getResultEntryDescriptors()[0].getName();
207             }
208         }
209         if ( input == null && parameterDescriptors.length == 1 && parameterDescriptors[0].isRequired()) {
210             throw new ProcessException(new ErrorMessage("requiredParameterMissing", new String JavaDoc[]{parameterDescriptors[0].getName()}));
211         } else if ( input == null && parameterDescriptors.length > 1 ) {
212             ParameterDescriptor requiredParameter = getRequiredParameter(parameterDescriptors);
213             if ( requiredParameter != null ) throw new ProcessException(new ErrorMessage("requiredParameterMissing", new String JavaDoc[]{ requiredParameter.getName()}));
214         } else {
215             try {
216                 // check for SimpleProcessor to avoid HashMap creation
217
if ( processor instanceof EnvironmentConsumer ) {
218                     Process.checkRequirements((EnvironmentConsumer)processor, context);
219                 }
220                 if ( processor instanceof SimpleProcessor ) {
221                     Value preparedValue = prepareValue(parameterDescriptors[0], input, context);
222                     input = ((SimpleProcessor)processor).process(preparedValue, context);
223                 } else {
224                     Map JavaDoc parameters = new HashMap JavaDoc();
225                     if ( parameterDescriptors.length == 1 ) {
226                         parameters.put(parameterDescriptors[0].getName(), prepareValue(parameterDescriptors[0], input, context));
227                     } else {
228                         for ( int i = 0; i < parameterDescriptors.length; i++ ) {
229                             if ( parameterDescriptors[i].isRequired() ) {
230                                 parameters.put(parameterDescriptors[i].getName(), prepareValue(parameterDescriptors[i], input, context));
231                             } else {
232                                 parameters.put(parameterDescriptors[i].getName(), parameterDescriptors[i].getDefaultValue());
233                             }
234                         }
235                         
236                     }
237                     Result processorResult = processor.process(parameters, context);
238                     input = processorResult.getResultEntries().get(resultKey);
239                 }
240             } catch ( Exception JavaDoc exception ) {
241                 throw new ProcessException(new ErrorMessage("parameterProcessingException", new String JavaDoc[] { simpleProcessorUri.toString(), exception.getMessage() }), exception);
242             }
243         }
244         return (Value)input;
245     }
246
247     public static void prepareValues(ParameterDescriptor[] parameterDescriptors, Map JavaDoc parameters, Context context) throws Exception JavaDoc {
248         for ( int i = 0; i < parameterDescriptors.length; i++ ) {
249             String JavaDoc parameterName = parameterDescriptors[i].getName();
250             Object JavaDoc parameterValue = parameters.get(parameterName);
251             Value preparedValue = prepareValue(parameterDescriptors[i], parameterValue, context);
252             parameters.put(parameterName, preparedValue);
253         }
254     }
255     
256     public static Value prepareValue(ParameterDescriptor parameterDescriptor, Object JavaDoc value, Context context) throws Exception JavaDoc {
257         Value preparedValue;
258         if ( value instanceof AnyValue ) {
259              value = ((AnyValue)value).load(context);
260         }
261         if ( value == null || value instanceof NullValue ) {
262             if ( parameterDescriptor.isRequired() ) {
263                 throw new ValidationException(new ErrorMessage("requiredParameterMissing", new String JavaDoc[] { parameterDescriptor.getName() }));
264             } else {
265                 preparedValue = parameterDescriptor.getDefaultValue();
266             }
267         } else {
268             preparedValue = parameterDescriptor.getValueDescriptor().valueOf(value, context);
269             parameterDescriptor.getValueDescriptor().validate(preparedValue, context);
270         }
271         return preparedValue;
272     }
273
274     public ProcessorDescriptor getProcessorDescriptor(URI uri) {
275         return (ProcessorDescriptor)processorDescriptors.get(uri);
276     }
277
278     public ProcessorDescriptor getProcessorDescriptor(Processor processor) {
279         for ( Iterator JavaDoc i = processorDescriptors.values().iterator(); i.hasNext(); ) {
280             ProcessorDescriptor processorDescriptor = (ProcessorDescriptor)i.next();
281             if ( processorDescriptor.getProcessor() == processor ) return processorDescriptor;
282         }
283         return null;
284     }
285
286     private void registerProcessor(URI uri, Processor processor) {
287     }
288
289     private static int countRequiredParameters(ParameterDescriptor[] descriptors) {
290         int count = 0;
291         for ( int i = 0; i < descriptors.length; i++ ) {
292             if ( descriptors[i].isRequired() ) {
293                 count++;
294             }
295         }
296         return count;
297     }
298
299     private static ParameterDescriptor getRequiredParameter(ParameterDescriptor[] descriptors) {
300         for ( int i = 0; i < descriptors.length; i++ ) {
301             if ( descriptors[i].isRequired() ) {
302                 return descriptors[i];
303             }
304         }
305         return null;
306     }
307
308     public class ConfigurationHandler extends DefaultSimpleImportHandler {
309         URI applicationUri;
310         List JavaDoc addedProcessors = new ArrayList JavaDoc();
311         List JavaDoc removedProcessors = new ArrayList JavaDoc();
312             
313         public ConfigurationHandler(URI applicationUri, List JavaDoc installedProcessors) {
314             this.applicationUri = applicationUri;
315             removedProcessors.addAll(installedProcessors);
316         }
317         
318         public void startElement(SimplePath path, String JavaDoc name, AttributesImpl JavaDoc attributes, String JavaDoc leadingCDdata) {
319             if (path.matches("processor")) {
320                 boolean modified = false, added = false;
321                 URI uri = new URIValue(attributes.getValue("uri"));
322                 removedProcessors.remove(uri);
323                 String JavaDoc configURI = attributes.getValue("config-uri");
324                 String JavaDoc processorName = attributes.getValue("name");
325                 String JavaDoc descriptionKey = attributes.getValue("description");
326                 String JavaDoc smallIcon = attributes.getValue("small-icon");
327                 String JavaDoc largeIcon = attributes.getValue("large-icon");
328                 String JavaDoc clazz = attributes.getValue("class");
329                 String JavaDoc bookmark = attributes.getValue("bookmark");
330                 Processor processor = (Processor)processorMap.get(uri);
331                 ProcessorDescriptor processorDescriptor = (ProcessorDescriptor)processorDescriptors.get(uri);
332                 try {
333                     if ( processor == null ) {
334                         processor = (Processor)processorClassLoader.loadClass(clazz).getConstructor(new Class JavaDoc[0]).newInstance(new Object JavaDoc[0]);
335                         added = true;
336                         modified = true;
337                     }
338                     if ( processorDescriptor == null ) {
339                         processorDescriptor = new ProcessorDescriptor(uri);
340                         modified = true;
341                     }
342                     if ( processorName == null ) processorName = uri.toString();
343                     if ( processorDescriptor.getName() == null || !processorDescriptor.getName().equals(processorName) ) {
344                         processorDescriptor.setName(processorName);
345                         modified = true;
346                     }
347                     if ( descriptionKey == null ) {
348                         descriptionKey = "processorManager/noProcessorDescriptionAvailable";
349                     }
350                     DefaultMessage description = null;
351                     if ( processorDescriptor.getDescription() == null || !processorDescriptor.getDescription().getId().equals(descriptionKey) ) {
352                         description = new DefaultMessage(descriptionKey);
353                         processorDescriptor.setDescription(description);
354                         modified = true;
355                     }
356                     if ( processorDescriptor.getProcessor() != processor ) {
357                         processorDescriptor.setProcessor(processor);
358                         modified = true;
359                     }
360                     URI smallIconUri = SMALL_DEFAULT_ICON, largeIconUri = LARGE_DEFAULT_ICON;
361                     if ( smallIcon != null ) smallIconUri = new URIValue(smallIcon);
362                     if ( largeIcon != null ) largeIconUri = new URIValue(largeIcon);
363                     if ( processorDescriptor.getSmallIcon() == null || !processorDescriptor.getSmallIcon().equals(smallIconUri) ) {
364                         processorDescriptor.setSmallIcon(smallIconUri);
365                         modified = true;
366                     }
367                     if ( processorDescriptor.getLargeIcon() == null || !processorDescriptor.getLargeIcon().equals(largeIconUri) ) {
368                         processorDescriptor.setLargeIcon(largeIconUri);
369                         modified = true;
370                     }
371                     if ( bookmark != null ) {
372                         boolean isBookmark = Boolean.valueOf(bookmark).booleanValue();
373                         if ( processorDescriptor.isBookmark() != isBookmark ) {
374                             processorDescriptor.setBookmark(isBookmark);
375                             modified = true;
376                         }
377                     }
378                     if ( processor instanceof ConfigurableProcessor && configURI != null ) {
379                         if ( !configURI.startsWith("/") ) {
380                             configURI = applicationUri.toString() + configURI;
381                         }
382                         URI configurationUri = new URIValue(configURI);
383                         if ( processorDescriptor.getConfiguration() == null || !processorDescriptor.getConfiguration().equals(configurationUri) ) {
384                             logger.log(Level.FINE, "Configuring processor with config-URI=" + configURI);
385                             processorDescriptor.setConfiguration(configurationUri);
386                             StreamableValue config = (StreamableValue)Projector.getRepository().getResource(configurationUri, Projector.getCredentials());
387                             ((ConfigurableProcessor)processor).configure(config);
388                             // listen for configuration changes
389
Subscriber subscriber = new ConfigurationListener();
390                             Projector.getRepository().subscribe("Update", configurationUri, 0, subscriber, Projector.getCredentials());
391                             configurationListeners.put(configurationUri, subscriber);
392                             configuredProcessors.put(configurationUri, processor);
393                             modified = true;
394                         }
395                     }
396                     if ( added ) {
397                         logger.log(Level.FINE, "Adding processor with URI=" + uri);
398                         addedProcessors.add(uri);
399                     }
400                     if ( modified ) {
401                         logger.log(Level.FINE, "Updating processor with URI=" + uri);
402                         processorMap.put(uri, processor);
403                         processorDescriptors.put(uri, processorDescriptor);
404                     }
405                 } catch (Exception JavaDoc e) {
406                     logger.log(Level.SEVERE, "Processor " + clazz + " could not be created or configured!", e);
407                 }
408             }
409         }
410
411         List JavaDoc getAddedProcessors() {
412             return addedProcessors;
413         }
414
415         List JavaDoc getRemovedProcessors() {
416             return removedProcessors;
417         }
418     }
419
420     class ConfigurationListener implements Subscriber {
421         public void notify(String JavaDoc uri, Map JavaDoc information) {
422             URI processorUri = new URIValue(uri);
423             Processor processor = (Processor)configuredProcessors.get(processorUri);
424             logger.log(Level.FINE, "Reloading processor with configuration URI='"+uri+"'");
425             try {
426                 StreamableValue config = (StreamableValue)Projector.getRepository().getResource(processorUri, Projector.getCredentials());
427                 ((ConfigurableProcessor)processor).configure(config);
428             } catch ( IOException JavaDoc e ) {
429                 logger.log(Level.SEVERE, "Configuration resource with URI='"+uri+"' could not be loaded!", e);
430             } catch ( ConfigurationException e ) {
431                 logger.log(Level.SEVERE, "Processor with configuration URI='" + uri + "' could not be reloaded! Configuration resource might be invalid!", e);
432             }
433         }
434     }
435     
436     class ConfiguredProcessor {
437         private String JavaDoc configUri;
438         private URI processorUri;
439
440         public ConfiguredProcessor(String JavaDoc configUri, URI processorUri) {
441             this.configUri = configUri;
442             this.processorUri = processorUri;
443         }
444
445         public String JavaDoc getConfigUri() {
446             return configUri;
447         }
448
449         public URI getProcessorUri() {
450             return processorUri;
451         }
452     }
453 }
Popular Tags