1 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 ; 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 ; 36 import java.util.Iterator ; 37 38 import java.util.zip.ZipFile ; 39 import java.util.zip.ZipEntry ; 40 import java.util.jar.JarEntry ; 41 import java.util.jar.JarInputStream ; 42 43 44 import java.io.File ; 45 import java.io.FileInputStream ; 46 import java.io.IOException ; 47 import java.io.FileNotFoundException ; 48 import java.io.InputStream ; 49 50 import java.nio.ByteBuffer ; 51 import java.security.PrivilegedAction ; 52 import java.security.AccessController ; 53 import java.net.URL ; 54 55 56 63 public class CmsDataLoader extends DataLoaderBase implements DataLoader 64 { 65 66 private static final String ARCHIVE_PATTERN = ".sar!|.war!|.jar!|.zip!|.tar!"; 67 private static final String 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 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 118 public boolean checkDataInitialized() throws PortalSetupException 119 { 120 boolean result = false; 121 String 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 result = false; 134 } 135 return result; 136 } 137 138 private void setupCMS() 139 { 140 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 secTokenString = m_cmsAccessConfig.getSecurityToken(); 146 m_securityToken = new SecurityToken(secTokenString == null ? new Object () : secTokenString); 147 m_nsat = Domain.accessNamespace(m_securityToken, Domain.getDefaultNamespace()); 148 } 149 150 151 156 protected StatementMetaData parseStatement(Element stmtElmt) throws PortalSetupException 157 { 158 return new CmsStatementMetaData(stmtElmt); 159 } 160 161 162 167 protected boolean executeStatements(List stmtList) throws PortalSetupException 168 { 169 boolean result = true; 170 if (null != stmtList && !stmtList.isEmpty()) 171 { 172 Iterator 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 run() throws Exception 205 { 206 boolean currInsResult = true; 207 List contentList = stmt.getContents(); 208 Iterator 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 th) 221 { 222 String 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 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 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 fixContentPath(String localDirPath, String contentLocation) 260 { 261 String 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 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 localDataDirectory = ((CmsDataLoaderConfig)this.getDataLoaderConfiguration()).getLocalDataDirectory(); 297 cmd.getContentLoaction(); 298 String contentLocationPath = fixContentPath(localDataDirectory, cmd.getContentLoaction()); 299 File contentFile = new File (contentLocationPath); 300 if (contentFile.exists()) 301 { 302 result = loadContentFromFileSystem(contentFile, cmd); 303 304 } 305 else 306 { 307 URL contentLoactionURL = 308 Thread.currentThread().getContextClassLoader().getResource(cmd.getContentLoaction()); 309 String 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 result = loadContentFromArchive(cmd, contentLoactionURL); 317 } 318 else 319 { 320 File content = new File (strUrl); 321 loadContentFromFileSystem(content, cmd); 322 } 323 324 } 325 return result; 326 } 327 328 338 private boolean loadContentFromArchive(ContentMetaData cmd, URL url) 339 throws CmsSetupException 340 { 341 String parentUri = cmd.getParentNodeUri(); 342 JarInputStream jis = null; 343 ZipEntry entry = null; 344 try 345 { 346 jis = ArchiveParser.getJarInputStream(url.toExternalForm()); 347 entry = jis.getNextEntry(); 348 while (null != entry) 349 { 350 String 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 addContentNode(jis, entry, contentEntryName, true); 367 jis.closeEntry(); 368 } 369 } 370 entry = jis.getNextEntry(); 371 } } 373 catch (IOException e) 374 { 375 try 376 { 377 Object content = url.openConnection().getContent(); 378 } 379 catch (Exception ex) 380 { 381 } 382 String 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 ie) 397 { 398 } 399 try 400 { 401 jis.close(); 402 } 403 catch (IOException th) 404 { 405 } 406 } 407 } 408 409 return true; 410 } 411 412 public void addContentNode(InputStream is, ZipEntry entry, String 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 ioe) 433 { 434 String 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 th) 440 { 441 throw new CmsSetupException("Unexpected error", th); 442 } 443 444 String extension = fileUri.substring(fileUri.lastIndexOf('.') + 1); 445 String 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 msg = "Failed to create content node: '" + fileUri + "'!"; 458 m_log.error(msg, e); 459 throw new CmsSetupException(msg, e); 460 } 461 } 462 463 467 public void addDirectoryNode(String 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 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 490 public boolean loadDirectory(File dir, String parentUri, boolean add) throws CmsSetupException 491 { 492 493 String 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 [] 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 file, String parentUri) throws CmsSetupException 522 { 523 524 525 if (parentUri == null) 526 { 527 parentUri = "/files"; 528 } 529 String name = file.getName(); 530 String fileUri = parentUri + '/' + name; 531 532 String extension = name.substring(name.lastIndexOf('.') + 1); 533 String 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 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 file) throws CmsSetupException 551 { 552 FileInputStream fis = null; 553 ByteBuffer buf = null; 554 byte[] finalBytes = null; 555 try 556 { 557 fis = new FileInputStream (file); 558 } 559 catch (FileNotFoundException e) 560 { 561 String 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 (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 ioe) 585 { 586 String 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 th) 592 { 593 throw new CmsSetupException("Unexpected error", th); 594 } 595 596 598 return finalBytes; 599 600 } 601 602 603 private long getFileSize(File file) 604 605 { 606 final File resourceFile = file; 607 608 PrivilegedAction action = new PrivilegedAction () 609 { 610 public Object run() 611 { 612 if (resourceFile.isDirectory()) 613 { 614 return new Long (-1); 615 } 616 617 return new Long (resourceFile.length()); 618 } 619 }; 620 621 long length = ((Long )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 |