KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > importer > ImporterBootstrap


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.importer;
18
19 import java.io.BufferedReader JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.InputStreamReader JavaDoc;
22 import java.io.Reader JavaDoc;
23 import java.io.UnsupportedEncodingException JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Locale JavaDoc;
26 import java.util.Properties JavaDoc;
27 import java.util.ResourceBundle JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 import javax.transaction.UserTransaction JavaDoc;
31
32 import org.alfresco.error.AlfrescoRuntimeException;
33 import org.alfresco.i18n.I18NUtil;
34 import org.alfresco.repo.security.authentication.AuthenticationComponent;
35 import org.alfresco.service.cmr.repository.NodeService;
36 import org.alfresco.service.cmr.repository.StoreRef;
37 import org.alfresco.service.cmr.view.ImporterBinding;
38 import org.alfresco.service.cmr.view.ImporterException;
39 import org.alfresco.service.cmr.view.ImporterProgress;
40 import org.alfresco.service.cmr.view.ImporterService;
41 import org.alfresco.service.cmr.view.Location;
42 import org.alfresco.service.namespace.NamespaceService;
43 import org.alfresco.service.namespace.QName;
44 import org.alfresco.service.transaction.TransactionService;
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47 import org.apache.commons.logging.impl.Log4JLogger;
48 import org.apache.log4j.Level;
49 import org.apache.log4j.Logger;
50 import org.springframework.context.ApplicationEvent;
51 import org.springframework.context.ApplicationListener;
52 import org.springframework.context.event.ContextRefreshedEvent;
53 import org.springframework.core.io.ClassPathResource;
54
55 /**
56  * Bootstrap Repository store.
57  *
58  * @author David Caruana
59  */

60 public class ImporterBootstrap implements ApplicationListener
61 {
62     // View Properties (used in setBootstrapViews)
63
public static final String JavaDoc VIEW_PATH_PROPERTY = "path";
64     public static final String JavaDoc VIEW_CHILDASSOCTYPE_PROPERTY = "childAssocType";
65     public static final String JavaDoc VIEW_MESSAGES_PROPERTY = "messages";
66     public static final String JavaDoc VIEW_LOCATION_VIEW = "location";
67     public static final String JavaDoc VIEW_ENCODING = "encoding";
68     
69     // Logger
70
private static final Log logger = LogFactory.getLog(ImporterBootstrap.class);
71     private boolean logEnabled = false;
72
73     // Dependencies
74
private boolean allowWrite = true;
75     private boolean useExistingStore = false;
76     private TransactionService transactionService;
77     private NamespaceService namespaceService;
78     private NodeService nodeService;
79     private ImporterService importerService;
80     private List JavaDoc<Properties JavaDoc> bootstrapViews;
81     private StoreRef storeRef = null;
82     private List JavaDoc<String JavaDoc> mustNotExistStoreUrls = null;
83     private Properties JavaDoc configuration = null;
84     private String JavaDoc strLocale = null;
85     private Locale JavaDoc locale = null;
86     private AuthenticationComponent authenticationComponent;
87     
88     // Bootstrap performed?
89
private boolean bootstrapPerformed = false;
90     
91     
92     /**
93      * Set whether we write or not
94      *
95      * @param write true (default) if the import must go ahead, otherwise no import will occur
96      */

97     public void setAllowWrite(boolean write)
98     {
99         this.allowWrite = write;
100     }
101
102     /**
103      * Set whether the importer bootstrap should only perform an import if the store
104      * being referenced doesn't already exist.
105      *
106      * @param useExistingStore true to allow imports into an existing store,
107      * otherwise false (default) to only import if the store doesn't exist.
108      */

109     public void setUseExistingStore(boolean useExistingStore)
110     {
111         this.useExistingStore = useExistingStore;
112     }
113
114     /**
115      * Sets the Transaction Service
116      *
117      * @param userTransaction the transaction service
118      */

119     public void setTransactionService(TransactionService transactionService)
120     {
121         this.transactionService = transactionService;
122     }
123     
124     /**
125      * Sets the namespace service
126      *
127      * @param namespaceService the namespace service
128      */

129     public void setNamespaceService(NamespaceService namespaceService)
130     {
131         this.namespaceService = namespaceService;
132     }
133
134     /**
135      * Sets the node service
136      *
137      * @param nodeService the node service
138      */

139     public void setNodeService(NodeService nodeService)
140     {
141         this.nodeService = nodeService;
142     }
143
144     /**
145      * Sets the importer service
146      *
147      * @param importerService the importer service
148      */

149     public void setImporterService(ImporterService importerService)
150     {
151         this.importerService = importerService;
152     }
153         
154     /**
155      * Set the authentication component
156      *
157      * @param authenticationComponent
158      */

159     public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
160     {
161         this.authenticationComponent = authenticationComponent;
162     }
163
164     /**
165      * Sets the bootstrap views
166      *
167      * @param bootstrapViews
168      */

169     public void setBootstrapViews(List JavaDoc<Properties JavaDoc> bootstrapViews)
170     {
171         this.bootstrapViews = bootstrapViews;
172     }
173
174     /**
175      * Sets the Store Ref to bootstrap into
176      *
177      * @param storeUrl
178      */

179     public void setStoreUrl(String JavaDoc storeUrl)
180     {
181         this.storeRef = new StoreRef(storeUrl);
182     }
183
184     /**
185      * If any of the store urls exist, the bootstrap does not take place
186      *
187      * @param storeUrls the list of store urls to check
188      */

189     public void setMustNotExistStoreUrls(List JavaDoc<String JavaDoc> storeUrls)
190     {
191         this.mustNotExistStoreUrls = storeUrls;
192     }
193     
194     /**
195      * Gets the Store Reference
196      *
197      * @return store reference
198      */

199     public StoreRef getStoreRef()
200     {
201         return this.storeRef;
202     }
203     
204     /**
205      * Sets the Configuration values for binding place holders
206      *
207      * @param configuration
208      */

209     public void setConfiguration(Properties JavaDoc configuration)
210     {
211         this.configuration = configuration;
212     }
213
214     /**
215      * Gets the Configuration values for binding place holders
216      *
217      * @return configuration
218      */

219     public Properties JavaDoc getConfiguration()
220     {
221         return configuration;
222     }
223     
224     /**
225      * Sets the Locale
226      *
227      * @param locale (language_country_variant)
228      */

229     public void setLocale(String JavaDoc locale)
230     {
231         // construct locale
232
StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(locale, "_");
233         int tokens = t.countTokens();
234         if (tokens == 1)
235         {
236            this.locale = new Locale JavaDoc(locale);
237         }
238         else if (tokens == 2)
239         {
240            this.locale = new Locale JavaDoc(t.nextToken(), t.nextToken());
241         }
242         else if (tokens == 3)
243         {
244            this.locale = new Locale JavaDoc(t.nextToken(), t.nextToken(), t.nextToken());
245         }
246
247         // store original
248
strLocale = locale;
249     }
250
251     /**
252      * Get Locale
253      *
254      * @return locale
255      */

256     public String JavaDoc getLocale()
257     {
258         return strLocale;
259     }
260     
261     /**
262      * Set log
263      *
264      * @param logEnabled
265      */

266     public void setLog(boolean logEnabled)
267     {
268         this.logEnabled = logEnabled;
269     }
270
271     /**
272      * Determine if bootstrap was performed?
273      *
274      * @return true => bootstrap was performed
275      */

276     public boolean hasPerformedBootstrap()
277     {
278         return bootstrapPerformed;
279     }
280     
281     /**
282      * Boostrap the Repository
283      */

284     public void bootstrap()
285     {
286         if (transactionService == null)
287         {
288             throw new ImporterException("Transaction Service must be provided");
289         }
290         if (namespaceService == null)
291         {
292             throw new ImporterException("Namespace Service must be provided");
293         }
294         if (nodeService == null)
295         {
296             throw new ImporterException("Node Service must be provided");
297         }
298         if (importerService == null)
299         {
300             throw new ImporterException("Importer Service must be provided");
301         }
302         if (storeRef == null)
303         {
304             throw new ImporterException("Store URL must be provided");
305         }
306
307         // initialise log level
308
// note: only supported with Log4J
309
if (logEnabled && logger instanceof Log4JLogger)
310         {
311             Logger log4JLogger = ((Log4JLogger)logger).getLogger();
312             log4JLogger.setLevel(Level.DEBUG);
313         }
314         
315         UserTransaction JavaDoc userTransaction = transactionService.getUserTransaction();
316         authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
317
318         try
319         {
320             userTransaction.begin();
321         
322             // check the repository exists, create if it doesn't
323
if (!performBootstrap())
324             {
325                 if (logger.isDebugEnabled())
326                     logger.debug("Store exists - bootstrap ignored: " + storeRef);
327             }
328             else if (!allowWrite)
329             {
330                 // we're in read-only node
331
logger.warn("Store does not exist, but mode is read-only: " + storeRef);
332             }
333             else
334             {
335                 // create the store if necessary
336
if (!nodeService.exists(storeRef))
337                 {
338                     storeRef = nodeService.createStore(storeRef.getProtocol(), storeRef.getIdentifier());
339                     if (logger.isDebugEnabled())
340                         logger.debug("Created store: " + storeRef);
341                 }
342     
343                 // bootstrap the store contents
344
if (bootstrapViews != null)
345                 {
346                     for (Properties JavaDoc bootstrapView : bootstrapViews)
347                     {
348                         String JavaDoc view = bootstrapView.getProperty(VIEW_LOCATION_VIEW);
349                         if (view == null || view.length() == 0)
350                         {
351                             throw new ImporterException("View file location must be provided");
352                         }
353                         String JavaDoc encoding = bootstrapView.getProperty(VIEW_ENCODING);
354                         
355                         // Create appropriate view reader
356
Reader JavaDoc viewReader = null;
357                         ACPImportPackageHandler acpHandler = null;
358                         if (view.endsWith(".acp"))
359                         {
360                             ClassPathResource acpResource = new ClassPathResource(view);
361                             acpHandler = new ACPImportPackageHandler(acpResource.getFile(), encoding);
362                         }
363                         else
364                         {
365                             viewReader = getReader(view, encoding);
366                         }
367                         
368                         // Create import location
369
Location importLocation = new Location(storeRef);
370                         String JavaDoc path = bootstrapView.getProperty(VIEW_PATH_PROPERTY);
371                         if (path != null && path.length() > 0)
372                         {
373                             importLocation.setPath(path);
374                         }
375                         String JavaDoc childAssocType = bootstrapView.getProperty(VIEW_CHILDASSOCTYPE_PROPERTY);
376                         if (childAssocType != null && childAssocType.length() > 0)
377                         {
378                             importLocation.setChildAssocType(QName.createQName(childAssocType, namespaceService));
379                         }
380                         
381                         // Create import binding
382
BootstrapBinding binding = new BootstrapBinding();
383                         binding.setConfiguration(configuration);
384                         binding.setLocation(importLocation);
385                         String JavaDoc messages = bootstrapView.getProperty(VIEW_MESSAGES_PROPERTY);
386                         if (messages != null && messages.length() > 0)
387                         {
388                             Locale JavaDoc bindingLocale = (locale == null) ? I18NUtil.getLocale() : locale;
389                             ResourceBundle JavaDoc bundle = ResourceBundle.getBundle(messages, bindingLocale);
390                             binding.setResourceBundle(bundle);
391                         }
392
393                         // Now import...
394
ImporterProgress importProgress = null;
395                         if (logger.isDebugEnabled())
396                         {
397                             importProgress = new ImportTimerProgress(logger);
398                             logger.debug("Importing " + view);
399                         }
400                         
401                         if (viewReader != null)
402                         {
403                             importerService.importView(viewReader, importLocation, binding, importProgress);
404                         }
405                         else
406                         {
407                             importerService.importView(acpHandler, importLocation, binding, importProgress);
408                         }
409                     }
410                 }
411                 
412                 // a bootstrap was performed
413
bootstrapPerformed = !useExistingStore;
414             }
415             userTransaction.commit();
416         }
417         catch(Throwable JavaDoc e)
418         {
419             // rollback the transaction
420
try { if (userTransaction != null) {userTransaction.rollback();} } catch (Exception JavaDoc ex) {}
421             try {authenticationComponent.clearCurrentSecurityContext(); } catch (Exception JavaDoc ex) {}
422             throw new AlfrescoRuntimeException("Bootstrap failed", e);
423         }
424         finally
425         {
426             authenticationComponent.clearCurrentSecurityContext();
427         }
428     }
429     
430     /**
431      * Get a Reader onto an XML view
432      *
433      * @param view the view location
434      * @param encoding the encoding of the view
435      * @return the reader
436      */

437     private Reader JavaDoc getReader(String JavaDoc view, String JavaDoc encoding)
438     {
439         // Get Input Stream
440
InputStream JavaDoc viewStream = getClass().getClassLoader().getResourceAsStream(view);
441         if (viewStream == null)
442         {
443             throw new ImporterException("Could not find view file " + view);
444         }
445
446         // Wrap in buffered reader
447
try
448         {
449             InputStreamReader JavaDoc inputReader = (encoding == null) ? new InputStreamReader JavaDoc(viewStream) : new InputStreamReader JavaDoc(viewStream, encoding);
450             BufferedReader JavaDoc reader = new BufferedReader JavaDoc(inputReader);
451             return reader;
452         }
453         catch (UnsupportedEncodingException JavaDoc e)
454         {
455             throw new ImporterException("Could not create reader for view " + view + " as encoding " + encoding + " is not supported");
456         }
457     }
458     
459     /**
460      * Bootstrap Binding
461      */

462     private static class BootstrapBinding implements ImporterBinding
463     {
464         private Properties JavaDoc configuration = null;
465         private ResourceBundle JavaDoc resourceBundle = null;
466         private Location bootstrapLocation = null;
467         
468         private static final String JavaDoc IMPORT_LOCATION_UUID = "bootstrap.location.uuid";
469         private static final String JavaDoc IMPORT_LOCATION_NODEREF = "bootstrap.location.noderef";
470         private static final String JavaDoc IMPORT_LOCATION_PATH = "bootstrap.location.path";
471         
472         
473         /**
474          * Set Import Configuration
475          *
476          * @param configuration
477          */

478         public void setConfiguration(Properties JavaDoc configuration)
479         {
480             this.configuration = configuration;
481         }
482
483         /**
484          * Get Import Configuration
485          *
486          * @return configuration
487          */

488         public Properties JavaDoc getConfiguration()
489         {
490             return this.configuration;
491         }
492         
493         /**
494          * Set Resource Bundle
495          *
496          * @param resourceBundle
497          */

498         public void setResourceBundle(ResourceBundle JavaDoc resourceBundle)
499         {
500             this.resourceBundle = resourceBundle;
501         }
502         
503         /**
504          * Set Location
505          *
506          * @param location
507          */

508         public void setLocation(Location location)
509         {
510             this.bootstrapLocation = location;
511         }
512         
513         /* (non-Javadoc)
514          * @see org.alfresco.service.cmr.view.ImporterBinding#getValue(java.lang.String)
515          */

516         public String JavaDoc getValue(String JavaDoc key)
517         {
518             String JavaDoc value = null;
519             if (configuration != null)
520             {
521                 value = configuration.getProperty(key);
522             }
523             if (value == null && resourceBundle != null)
524             {
525                 value = resourceBundle.getString(key);
526             }
527             if (value == null && bootstrapLocation != null)
528             {
529                 if (key.equals(IMPORT_LOCATION_UUID))
530                 {
531                     value = bootstrapLocation.getNodeRef().getId();
532                 }
533                 else if (key.equals(IMPORT_LOCATION_NODEREF))
534                 {
535                     value = bootstrapLocation.getNodeRef().toString();
536                 }
537                 else if (key.equals(IMPORT_LOCATION_PATH))
538                 {
539                     value = bootstrapLocation.getPath();
540                 }
541             }
542             
543             return value;
544         }
545
546         /*
547          * (non-Javadoc)
548          * @see org.alfresco.service.cmr.view.ImporterBinding#getUUIDBinding()
549          */

550         public UUID_BINDING getUUIDBinding()
551         {
552             // always use create new strategy for bootstrap import
553
return UUID_BINDING.CREATE_NEW;
554         }
555
556         /*
557          * (non-Javadoc)
558          * @see org.alfresco.service.cmr.view.ImporterBinding#searchWithinTransaction()
559          */

560         public boolean allowReferenceWithinTransaction()
561         {
562             return true;
563         }
564     }
565
566     /**
567      * Determine if bootstrap should take place
568      *
569      * @return true => yes, it should
570      */

571     private boolean performBootstrap()
572     {
573         if (useExistingStore)
574         {
575             // it doesn't matter if the store exists or not
576
return true;
577         }
578         else if (nodeService.exists(storeRef))
579         {
580             return false;
581         }
582         else if (mustNotExistStoreUrls != null)
583         {
584             for (String JavaDoc storeUrl : mustNotExistStoreUrls)
585             {
586                 StoreRef storeRef = new StoreRef(storeUrl);
587                 if (nodeService.exists(storeRef))
588                 {
589                     return false;
590                 }
591             }
592         }
593         
594         return true;
595     }
596
597     /*
598      * (non-Javadoc)
599      * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
600      */

601     public void onApplicationEvent(ApplicationEvent event)
602     {
603         if (event instanceof ContextRefreshedEvent)
604         {
605             bootstrap();
606         }
607     }
608     
609 }
610
Popular Tags