KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > setup > impl > dl > cmsloader > CmsDataLoader


1 /*****************************************
2  * *
3  * JBoss Portal: The OpenSource Portal *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  *****************************************/

9 package org.jboss.portal.setup.impl.dl.cmsloader;
10
11 import org.jboss.portal.setup.dl.DataLoader;
12 import org.jboss.portal.setup.PortalSetupException;
13 import org.jboss.portal.setup.CmsSetupException;
14 import org.jboss.portal.setup.util.ArchiveParser;
15 import org.jboss.portal.setup.util.GrowableByteBuffer;
16 import org.jboss.portal.setup.config.CmsAccessConfig;
17 import org.jboss.portal.setup.impl.dl.DataLoaderBase;
18 import org.jboss.portal.setup.impl.dl.StatementMetaData;
19 import org.jboss.portal.setup.impl.dl.StatementType;
20 import org.jboss.portal.cms.CMS;
21 import org.jboss.portal.cms.NodeFactory;
22 import org.jboss.portal.cms.Node;
23 import org.jboss.portal.cms.NodeException;
24 import org.jboss.portal.cms.Content;
25 import org.jboss.portal.common.transaction.Transactions;
26 import org.jboss.portal.common.transaction.NestedException;
27 import org.w3c.dom.Element JavaDoc;
28 import org.apache.slide.authenticate.SecurityToken;
29 import org.apache.slide.authenticate.CredentialsToken;
30 import org.apache.slide.common.Domain;
31 import org.apache.slide.common.NamespaceAccessToken;
32 import org.apache.slide.common.SlideTokenImpl;
33 import org.apache.log4j.Logger;
34
35 import java.util.List JavaDoc;
36 import java.util.Iterator JavaDoc;
37
38 import java.util.zip.ZipFile JavaDoc;
39 import java.util.zip.ZipEntry JavaDoc;
40 import java.util.jar.JarEntry JavaDoc;
41 import java.util.jar.JarInputStream JavaDoc;
42
43
44 import java.io.File JavaDoc;
45 import java.io.FileInputStream JavaDoc;
46 import java.io.IOException JavaDoc;
47 import java.io.FileNotFoundException JavaDoc;
48 import java.io.InputStream JavaDoc;
49
50 import java.nio.ByteBuffer JavaDoc;
51 import java.security.PrivilegedAction JavaDoc;
52 import java.security.AccessController JavaDoc;
53 import java.net.URL JavaDoc;
54
55
56 /**
57  * @author <a HREF="mailto:palber@novell.com">Polina Alber</a>
58  * Date: May 2, 2005; Time: 12:32:34 AM
59  * @since JBoss portal 2.0
60  * Class org.jboss.portal.setup.impl.dl.cmsloader.CmsDataLoader performs
61  * Content data loading.
62  */

63 public class CmsDataLoader extends DataLoaderBase implements DataLoader
64 {
65
66    private static final String JavaDoc ARCHIVE_PATTERN = ".sar!|.war!|.jar!|.zip!|.tar!";
67    private static final String JavaDoc IS_ARCHIVE_PATTERN = "jar$|zip$|tar$";
68    private Logger m_log = Logger.getLogger(CmsDataLoader.class);
69    private CMS m_cms = null;
70    private SecurityToken m_securityToken = null;
71    private NamespaceAccessToken m_nsat = null;
72    private NodeFactory m_nodeFactory = null;
73    private CMSMimeMappings m_mimeMappings = null;
74    private static final int READ_BLOCK_SIZE = 8192;
75    private CmsAccessConfig m_cmsAccessConfig = null;
76    private boolean m_useTransaction = false;
77    private SlideTokenImpl m_slideToken = null;
78
79
80    public CmsDataLoader() throws CmsSetupException
81    {
82       super();
83       m_mimeMappings = new CMSMimeMappings();
84
85    }
86
87    public void setCmsAccessConfig(CmsAccessConfig cmsConfig)
88    {
89       m_cmsAccessConfig = cmsConfig;
90       m_useTransaction = cmsConfig.getUseTransaction();
91       setupCMS();
92    }
93
94    /**
95     * destroy DataLoader and cleans all resources
96     *
97     * @throws PortalSetupException
98     */

99    public void destroy() throws PortalSetupException
100    {
101       m_cms = null;
102       m_securityToken = null;
103       m_nsat = null;
104       m_nodeFactory = null;
105       m_mimeMappings = null;
106       if (m_log.isInfoEnabled())
107       {
108          m_log.info("Destroying CMS data loader!");
109       }
110
111    }
112
113    /**
114     * @return boolean flag; when true means that database data have been initialized
115     * @throws PortalSetupException in case of an error: database schema have not been loaded,
116     * cannot connect to database instance, etc.
117     */

118    public boolean checkDataInitialized() throws PortalSetupException
119    {
120       boolean result = false;
121       String JavaDoc nodeURI = getDataLoaderConfiguration().getDataQueryString();
122       try
123       {
124          Node node = m_nodeFactory.getNode(m_nsat, nodeURI);
125          if (node.exists())
126          {
127             result = true;
128          }
129       }
130       catch (NodeException ne)
131       {
132          //assuming data does not exists, skipping exception
133
result = false;
134       }
135       return result;
136    }
137
138    private void setupCMS()
139    {
140       //locate CMS mbean then set it up
141
m_slideToken = new SlideTokenImpl(new CredentialsToken(m_cmsAccessConfig.getCmsCredentials()));
142       m_slideToken.setForceStoreEnlistment(true);
143       m_cms = CMS.getCMS();
144       m_nodeFactory = m_cms.getNodeFactory();
145       String JavaDoc secTokenString = m_cmsAccessConfig.getSecurityToken();
146       m_securityToken = new SecurityToken(secTokenString == null ? new Object JavaDoc() : secTokenString);
147       m_nsat = Domain.accessNamespace(m_securityToken, Domain.getDefaultNamespace());
148    }
149
150
151    /**
152     * @param stmtElmt a statement element
153     * @return a statement metadata
154     * @throws PortalSetupException upon errors in meta data creation
155     */

156    protected StatementMetaData parseStatement(Element JavaDoc stmtElmt) throws PortalSetupException
157    {
158       return new CmsStatementMetaData(stmtElmt);
159    }
160
161
162    /**
163     * @param stmtList a list of statement metadata objects
164     * @return a boolean flag, when true means that execution succedded
165     * @throws PortalSetupException upon errors in execution statements
166     */

167    protected boolean executeStatements(List JavaDoc stmtList) throws PortalSetupException
168    {
169       boolean result = true;
170       if (null != stmtList && !stmtList.isEmpty())
171       {
172          Iterator JavaDoc iter = stmtList.iterator();
173          while (iter.hasNext() && result)
174          {
175             CmsStatementMetaData stmt = (CmsStatementMetaData)iter.next();
176             result = executeStatement(stmt);
177
178          }
179       }
180       return result;
181    }
182
183    private boolean executeStatement(CmsStatementMetaData stmt) throws CmsSetupException
184    {
185       StatementType type = stmt.getType();
186       if (StatementType.INSERT == type)
187       {
188          processInsertCmsContent(stmt);
189       }
190       else
191       {
192          throw new CmsSetupException("Unsupported statement type = '" + type.toString() +
193             "'specified for CMS data loader!");
194       }
195       return true;
196    }
197
198    private void processCmsContentWithTransaction(final CmsStatementMetaData stmt) throws CmsSetupException
199    {
200       try
201       {
202          Transactions.required(m_nsat.getTransactionManager(), new Transactions.Runnable()
203          {
204             public Object JavaDoc run() throws Exception JavaDoc
205             {
206                boolean currInsResult = true;
207                List JavaDoc contentList = stmt.getContents();
208                Iterator JavaDoc iter = contentList.iterator();
209                while (iter.hasNext() && currInsResult)
210                {
211                   try
212                   {
213                      ContentMetaData cmd = (ContentMetaData)iter.next();
214                      currInsResult = loadContent(cmd);
215                   }
216                   catch (CmsSetupException cse)
217                   {
218                      throw cse;
219                   }
220                   catch (Throwable JavaDoc th)
221                   {
222                      String JavaDoc msg = "Got unexpected error upon CMS content data loading!";
223                      m_log.error(msg, th);
224                      throw new CmsSetupException(msg, th);
225                   }
226                   if (!currInsResult)
227                   {
228                      String JavaDoc msg = "Failed to load data for unknown reason!";
229                      m_log.error(msg);
230                      throw new CmsSetupException("Failed to load data for unknown reason!");
231                   }
232                }
233                //just empty return
234
return null;
235             }
236          });
237       }
238       catch (NestedException e)
239       {
240          throw new CmsSetupException(e);
241       }
242    }
243
244    private void processInsertCmsContent(CmsStatementMetaData stmt) throws CmsSetupException
245    {
246
247       if (m_useTransaction)
248       {
249          processCmsContentWithTransaction(stmt);
250       }
251       else
252       {
253          throw new CmsSetupException("Unsupported mode for content data loading: use of transaction is required!");
254       }
255
256
257    }
258
259    private String JavaDoc fixContentPath(String JavaDoc localDirPath, String JavaDoc contentLocation)
260    {
261       String JavaDoc contentLocationPath = localDirPath;
262       if (File.separatorChar != '/')
263       {
264          contentLocation.replace('/', File.separatorChar);
265       }
266       if (contentLocation.charAt(contentLocation.length() - 1) == File.separatorChar)
267       {
268          contentLocation = contentLocation.substring(0, contentLocation.length() - 2);
269       }
270       if (localDirPath.charAt(localDirPath.length() - 1) != File.separatorChar &&
271          contentLocation.charAt(0) != File.separatorChar)
272       {
273          contentLocationPath = localDirPath + File.separatorChar + contentLocation;
274       }
275       return contentLocationPath;
276    }
277
278    private boolean loadContentFromFileSystem(File JavaDoc content, ContentMetaData cmd) throws CmsSetupException
279    {
280       boolean result = false;
281       if (content.isDirectory())
282       {
283          result = loadDirectory(content, cmd.getParentNodeUri(), false);
284       }
285       else
286       {
287          result = loadFile(content, "content");
288       }
289       return result;
290    }
291
292
293    private boolean loadContent(ContentMetaData cmd) throws CmsSetupException
294    {
295       boolean result = false;
296       String JavaDoc localDataDirectory = ((CmsDataLoaderConfig)this.getDataLoaderConfiguration()).getLocalDataDirectory();
297       cmd.getContentLoaction();
298       String JavaDoc contentLocationPath = fixContentPath(localDataDirectory, cmd.getContentLoaction());
299       File JavaDoc contentFile = new File JavaDoc(contentLocationPath);
300       if (contentFile.exists())
301       {
302          result = loadContentFromFileSystem(contentFile, cmd);
303
304       }
305       else
306       {
307          URL JavaDoc contentLoactionURL =
308             Thread.currentThread().getContextClassLoader().getResource(cmd.getContentLoaction());
309          String JavaDoc strUrl = contentLoactionURL.getFile();
310          if ((strUrl.indexOf(".sar!") > 0) ||
311             (strUrl.indexOf(".jar!") > 0) ||
312             (strUrl.indexOf(".war!") > 0) ||
313             (strUrl.indexOf(".zip!") > 0))
314          {
315             //we have content location within archive
316
result = loadContentFromArchive(cmd, contentLoactionURL);
317          }
318          else
319          {
320             File JavaDoc content = new File JavaDoc(strUrl);
321             loadContentFromFileSystem(content, cmd);
322          }
323
324       }
325       return result;
326    }
327
328    /**
329     * Loads content from a specified location in archive: for now we can only load from
330     * jar, zip, or sar
331     *
332     * @param cmd - content metadata object
333     * @param url - content uri,
334     * that include archive name this content location belongs to
335     * @return boolean flag, when true indicates that request to load content succeded
336     * @throws CmsSetupException in case of an error
337     */

338    private boolean loadContentFromArchive(ContentMetaData cmd, URL JavaDoc url)
339       throws CmsSetupException
340    {
341       String JavaDoc parentUri = cmd.getParentNodeUri();
342       JarInputStream JavaDoc jis = null;
343       ZipEntry JavaDoc entry = null;
344       try
345       {
346          jis = ArchiveParser.getJarInputStream(url.toExternalForm());
347          entry = jis.getNextEntry();
348          while (null != entry)
349          {
350             String JavaDoc contentEntryName = entry.getName();
351
352             if (contentEntryName.startsWith(cmd.getContentLoaction()))
353             {
354                contentEntryName = ArchiveParser.cleanUpEntryName(contentEntryName, false);
355                if (entry.isDirectory())
356                {
357                   if (!contentEntryName.equals(parentUri))
358                   {
359                      addDirectoryNode(contentEntryName, true);
360                      jis.closeEntry();
361                   }
362                }
363                else
364                {
365                   //got file now all fun begin
366
addContentNode(jis, entry, contentEntryName, true);
367                   jis.closeEntry();
368                }
369             }
370             entry = jis.getNextEntry();
371          } //end of while entry != null
372
}
373       catch (IOException JavaDoc e)
374       {
375          try
376          {
377             Object JavaDoc content = url.openConnection().getContent();
378          }
379          catch (Exception JavaDoc ex)
380          {
381          }
382          String JavaDoc msg = "Failed to parse specified archive file and obtain list" + "" +
383             " of enteries correspondig for the specified path '" + cmd.getContentLoaction() + "'";
384          m_log.error(msg, e);
385
386          throw new CmsSetupException(msg, e);
387       }
388       finally
389       {
390          if (jis != null)
391          {
392             try
393             {
394                jis.closeEntry();
395             }
396             catch (IOException JavaDoc ie)
397             {
398             }
399             try
400             {
401                jis.close();
402             }
403             catch (IOException JavaDoc th)
404             {
405             }
406          }
407       }
408
409       return true;
410    }
411
412    public void addContentNode(InputStream JavaDoc is, ZipEntry JavaDoc entry, String JavaDoc fileUri, boolean requrcive)
413       throws CmsSetupException
414    {
415
416       GrowableByteBuffer buffer = new GrowableByteBuffer();
417
418       byte[] bytes = new byte[READ_BLOCK_SIZE];
419       byte[] finalBytes = null;
420       int readCount = 0;
421       try
422       {
423          while ((readCount = is.read(bytes, 0, READ_BLOCK_SIZE)) > 0)
424          {
425
426             buffer.write(bytes, 0, readCount);
427          }
428          buffer.flip();
429          finalBytes = buffer.getBytes();
430
431       }
432       catch (IOException JavaDoc ioe)
433       {
434          String JavaDoc msg = "Failed to read bytes for a file!";
435          m_log.error(msg, ioe);
436          buffer = null;
437          throw new CmsSetupException(msg, ioe);
438       }
439       catch (Throwable JavaDoc th)
440       {
441          throw new CmsSetupException("Unexpected error", th);
442       }
443
444       String JavaDoc extension = fileUri.substring(fileUri.lastIndexOf('.') + 1);
445       String JavaDoc mimeType = m_mimeMappings.getMimeType(extension);
446       if (null == mimeType)
447       {
448          throw new CmsSetupException("Cannot determine mime type for file extension: '" + extension + "'");
449       }
450       try
451       {
452          Node node = m_nodeFactory.getNode(m_nsat, fileUri);
453          node.createContent(new Content(finalBytes, mimeType), true);
454       }
455       catch (NodeException e)
456       {
457          String JavaDoc msg = "Failed to create content node: '" + fileUri + "'!";
458          m_log.error(msg, e);
459          throw new CmsSetupException(msg, e);
460       }
461    }
462
463    /*
464    * Creates a slide directory node
465    *
466    */

467    public void addDirectoryNode(String JavaDoc nodeUri, boolean requrcive) throws CmsSetupException
468    {
469       Node dirNode = null;
470       try
471       {
472          dirNode = m_nodeFactory.getNode(m_nsat, nodeUri);
473          dirNode.createDir(requrcive);
474       }
475       catch (NodeException e)
476       {
477          String JavaDoc msg = "Failed to create directory '" + nodeUri + "' node in CMS!";
478          m_log.error(msg, e);
479          throw new CmsSetupException(msg, e);
480       }
481
482    }
483
484    /**
485     * Read all mapping documents from a directory tree. Assume that any
486     * file named <tt>*.hbm.xml</tt> is a mapping document.
487     *
488     * @param dir a directory
489     */

490    public boolean loadDirectory(File JavaDoc dir, String JavaDoc parentUri, boolean add) throws CmsSetupException
491    {
492
493       //crete dir node
494
String JavaDoc nodeUri = null;
495       if (add)
496       {
497          nodeUri = parentUri == null ? '/' + dir.getName() : parentUri + '/' + dir.getName();
498          addDirectoryNode(nodeUri, false);
499
500       }
501       else
502       {
503          nodeUri = parentUri;
504       }
505
506       File JavaDoc[] files = dir.listFiles();
507       for (int i = 0; i < files.length; i++)
508       {
509          if (files[i].isDirectory())
510          {
511             loadDirectory(files[i], nodeUri, true);
512          }
513          else
514          {
515             loadFile(files[i], nodeUri);
516          }
517       }
518       return true;
519    }
520
521    private boolean loadFile(File JavaDoc file, String JavaDoc parentUri) throws CmsSetupException
522    {
523
524
525       if (parentUri == null)
526       {
527          parentUri = "/files";
528       }
529       String JavaDoc name = file.getName();
530       String JavaDoc fileUri = parentUri + '/' + name;
531
532       String JavaDoc extension = name.substring(name.lastIndexOf('.') + 1);
533       String JavaDoc mimeType = m_mimeMappings.getMimeType(extension);
534       byte[] bytes = getByteForFile(file);
535       try
536       {
537          Node node = m_nodeFactory.getNode(m_nsat, fileUri);
538          node.createContent(new Content(bytes, mimeType), true);
539       }
540       catch (NodeException e)
541       {
542          String JavaDoc msg = "Failed to create content node: '" + fileUri + "'!";
543          m_log.error(msg, e);
544          throw new CmsSetupException(msg, e);
545       }
546
547       return true;
548    }
549
550    private byte[] getByteForFile(File JavaDoc file) throws CmsSetupException
551    {
552       FileInputStream JavaDoc fis = null;
553       ByteBuffer buf = null;
554       byte[] finalBytes = null;
555       try
556       {
557          fis = new FileInputStream JavaDoc(file);
558       }
559       catch (FileNotFoundException JavaDoc e)
560       {
561          String JavaDoc msg = "Failed to create input stream for a file!";
562          m_log.error(msg, e);
563          throw new CmsSetupException(msg, e);
564       }
565
566
567       int readCount;
568       int size = new Long JavaDoc(this.getFileSize(file)).intValue();
569       buf = ByteBuffer.allocate(size);
570       finalBytes = new byte[size];
571
572       byte[] bytes = new byte[READ_BLOCK_SIZE];
573       int offset = 0;
574       try
575       {
576          while ((readCount = fis.read(bytes, 0, READ_BLOCK_SIZE)) > 0)
577          {
578
579             buf.put(bytes, 0, readCount);
580          }
581          buf.rewind();
582          buf.get(finalBytes);
583       }
584       catch (IOException JavaDoc ioe)
585       {
586          String JavaDoc msg = "Failed to read bytes for a file!";
587          m_log.error(msg, ioe);
588          buf = null;
589          throw new CmsSetupException(msg, ioe);
590       }
591       catch (Throwable JavaDoc th)
592       {
593          throw new CmsSetupException("Unexpected error", th);
594       }
595
596       //buf.reset();
597

598       return finalBytes;
599
600    }
601
602
603    private long getFileSize(File JavaDoc file)
604
605    {
606       final File JavaDoc resourceFile = file;
607
608       PrivilegedAction JavaDoc action = new PrivilegedAction JavaDoc()
609       {
610          public Object JavaDoc run()
611          {
612             if (resourceFile.isDirectory())
613             {
614                return new Long JavaDoc(-1);
615             }
616
617             return new Long JavaDoc(resourceFile.length());
618          }
619       };
620
621       long length = ((Long JavaDoc)AccessController.doPrivileged(action)).longValue();
622       if (length == 0L)
623       {
624          return -1L;
625       }
626
627       return length;
628
629    }
630
631
632 }
633
Popular Tags