1 13 19 package org.pentaho.repository.filebased.solution; 20 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.FileNotFoundException ; 24 import java.io.FileOutputStream ; 25 import java.io.FilenameFilter ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.InputStreamReader ; 29 import java.io.Reader ; 30 import java.net.URL ; 31 import java.net.URLClassLoader ; 32 import java.nio.channels.FileChannel ; 33 import java.util.ArrayList ; 34 import java.util.HashMap ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 import java.util.Locale ; 38 import java.util.Properties ; 39 import java.util.StringTokenizer ; 40 import javax.activation.DataSource ; 41 import javax.activation.FileDataSource ; 42 import javax.activation.URLDataSource ; 43 import org.apache.commons.collections.buffer.BoundedFifoBuffer; 44 import org.apache.commons.fileupload.FileItem; 45 import org.apache.commons.logging.Log; 46 import org.apache.commons.logging.LogFactory; 47 import org.dom4j.Document; 48 import org.dom4j.DocumentHelper; 49 import org.dom4j.Element; 50 import org.dom4j.Node; 51 import org.pentaho.core.repository.ISolutionRepository; 52 import org.pentaho.core.runtime.IRuntimeContext; 53 import org.pentaho.core.session.IPentahoSession; 54 import org.pentaho.core.solution.ActionResource; 55 import org.pentaho.core.solution.IActionResource; 56 import org.pentaho.core.solution.IActionSequence; 57 import org.pentaho.core.solution.SequenceDefinition; 58 import org.pentaho.core.solution.SolutionReposUtil; 59 import org.pentaho.core.system.PentahoMessenger; 60 import org.pentaho.core.system.PentahoSystem; 61 import org.pentaho.core.util.XmlHelper; 62 import org.pentaho.messages.Messages; 63 import org.pentaho.messages.util.LocaleHelper; 64 import org.pentaho.util.FileHelper; 65 import org.pentaho.util.HttpUtil; 66 67 72 public class SolutionRepository extends PentahoMessenger implements ISolutionRepository { 73 76 private static final long serialVersionUID = -8270135463210017284L; 77 78 private static final String ROOT_NODE_NAME = "repositiory"; 80 private static final String LOCATION_ATTR_NAME = "location"; 82 private static final String ENTRY_NODE_NAME = "entry"; 84 private static final String TYPE_ATTR_NAME = "type"; 86 private static final String NAME_ATTR_NAME = "name"; 88 private static final String DIRECTORY_ATTR = "directory"; 90 private static final String FILE_ATTR = "file"; 92 private static final String EMPTY_STR = ""; 94 private String rootPath; 95 96 private Document repository; 97 98 private static final boolean debug = PentahoSystem.debug; 99 100 private static SolutionRepository solutionRepository; 101 102 private IPentahoSession session; 103 104 private BoundedFifoBuffer cache; 105 106 private HashMap cacheMap; 107 108 private int cacheSize = 0; 109 110 private Locale locale; 111 112 private static String LOG_NAME = "SOLUTION-REPOSITORY"; 114 private File rootFile; 115 116 private static final Log logger = LogFactory.getLog(SolutionRepository.class); 117 118 private static HashMap propertyMap = new HashMap (); 119 120 public Log getLogger() { 121 return logger; 122 } 123 124 public SolutionRepository() { 125 locale = LocaleHelper.getLocale(); 126 init(); 127 } 128 129 private void init() { 130 repository = null; 131 cacheSize = 0; 132 try { 133 cacheSize = Integer.parseInt(PentahoSystem.getSystemSetting("solution-repository/cache-size", "0")); } catch (NumberFormatException e) { 135 } 136 if (cacheSize > 0) { 137 cacheMap = new HashMap (); 138 cache = new BoundedFifoBuffer(cacheSize); 139 } 140 } 141 142 public void setLocale(Locale locale) { 143 if (!this.locale.equals(locale)) { 144 init(); 145 } 146 this.locale = locale; 147 } 148 149 public ClassLoader getClassLoader(String path) { 150 File localeDir = new File (PentahoSystem.getApplicationContext().getSolutionPath(path)); 151 try { 152 URL localeDirUrl = localeDir.toURL(); 153 URLClassLoader loader = new URLClassLoader (new URL [] { localeDirUrl }); 154 return loader; 155 } catch (Exception e) { 156 } 157 return null; 158 } 159 160 public void setSession(IPentahoSession session) { 161 this.session = session; 162 } 163 164 public static SolutionRepository getInstance(IPentahoSession session) { 165 if (solutionRepository == null) { 166 solutionRepository = new SolutionRepository(); 167 solutionRepository.init(session); 168 } 169 return solutionRepository; 170 } 171 172 public IActionSequence getActionSequence(String solutionName, String actionPath, String sequenceName, int localLoggingLevel, int actionOperation) { 173 String action; 174 if (actionPath != null && !"".equals(actionPath)) { action = solutionName + File.separator + actionPath + File.separator + sequenceName; 176 } else { 177 action = solutionName + File.separator + sequenceName; 178 } 179 IActionSequence actionSequence; 180 if (cacheSize > 0) { 181 actionSequence = (IActionSequence) cacheMap.get(action); 182 if (actionSequence != null) { 183 cache.remove(actionSequence); 185 cache.add(actionSequence); 186 return actionSequence; 187 } 188 } 189 Document actionSequenceDocument = getSolutionDocument(action); 190 if (actionSequenceDocument == null) { 191 return null; 192 } 193 actionSequence = SequenceDefinition.ActionSequenceFactory(actionSequenceDocument, sequenceName, actionPath, solutionName, this, PentahoSystem.getApplicationContext(), localLoggingLevel); 194 if (actionSequence == null) { 195 return null; 196 } 197 if (cacheSize > 0) { 198 cacheMap.put(action, actionSequence); 200 if (cache.size() >= cacheSize) { 201 IActionSequence removed = (IActionSequence) cache.remove(); 202 String removedName = removed.getSolutionName() + File.separator + removed.getSolutionPath() + File.separator + removed.getSequenceName(); 203 cacheMap.remove(removedName); 204 } 205 cache.add(actionSequence); 206 } 207 return actionSequence; 208 } 209 210 public Document getSolutionDocument(String solutionName, String actionPath, String actionName) { 211 return getSolutionDocument(solutionName + File.separator + actionPath + File.separator + actionName); 212 } 213 214 public Document getSolutionDocument(String documentPath) { 215 File file = getFile(documentPath, false); 217 if (file == null) { 218 return null; 219 } 220 Document document = XmlHelper.getDocFromFile(file); 221 if (document == null && file.exists()) { 222 error(Messages.getString("SolutionRepository.ERROR_0009_INVALID_DOCUMENT", documentPath)); return null; 225 } 226 localizeDoc(document, file); 227 return document; 228 } 229 230 private File getFile(String path, boolean create) { 231 File f = new File (PentahoSystem.getApplicationContext().getSolutionPath(path)); 232 if (!f.exists() && !create) { 233 error(Messages.getErrorString("SolutionRepository.ERROR_0001_FILE_DOES_NOT_EXIST", path)); return null; 235 } 236 if (!f.exists()) { 237 f.mkdirs(); 238 } 239 if (debug) 241 debug(Messages.getErrorString("SolutionRepository.DEBUG_FILE_PATH", f.getAbsolutePath())); return f; 243 } 244 245 public void init(IPentahoSession pentahoSession) { 246 this.session = pentahoSession; 247 rootFile = getFile("", false); rootPath = rootFile.getAbsolutePath() + File.separator; 249 setLogId(LOG_NAME + ": "); } 251 252 private File getFile(IRuntimeContext runtimeContext, String path) { 253 if (runtimeContext == null) { 254 error(Messages.getErrorString("SolutionRepository.ERROR_0002_NULL_RUNTIME_CONTEXT")); return null; 256 } 257 File f = getFile(runtimeContext.getSolutionName() + File.separator + path, false); 258 if (!f.exists()) { 259 error(Messages.getErrorString("SolutionRepository.ERROR_0003_NULL_SOLUTION_FILE", path)); return null; 261 } 262 if (debug) 264 debug(Messages.getString("SolutionRepository.DEBUG_FILE_PATH", f.getAbsolutePath())); return f; 266 } 267 268 public String getAbsolutePath(IRuntimeContext runtimeContext, String path) { 269 return rootPath + File.separator + runtimeContext.getSolutionName() + File.separator + path; 271 } 272 273 public String getActionDefinition(IRuntimeContext runtimeContext, String actionPath) { 274 if ((runtimeContext == null) || (runtimeContext.getInstanceId() == null) || (runtimeContext.getActionName() == null)) { 276 error(Messages.getErrorString("SolutionRepository.ERROR_0004_INVALID_CONTEXT")); } 278 genLogIdFromInfo(runtimeContext.getInstanceId(), LOG_NAME, runtimeContext.getActionName()); 279 File f = getFile(runtimeContext, actionPath); 280 if (f == null) { 281 error(Messages.getErrorString("SolutionRepository.ERROR_0005_INVALID_SOLUTION_FILE") + actionPath); } 283 return FileHelper.getStringFromFile(f); 284 } 285 286 public Document getActionDefinitionDocument(IRuntimeContext runtimeContext, String actionPath) { 287 genLogIdFromInfo(runtimeContext.getInstanceId(), LOG_NAME, runtimeContext.getActionName()); 289 File f = getFile(runtimeContext, actionPath); 290 if (f == null) { 291 return null; 292 } 293 return XmlHelper.getDocFromFile(f); 294 } 295 296 public void publish(IPentahoSession localSession, int localLoggingLevel) { 298 this.loggingLevel = localLoggingLevel; 300 File rootDir = getFile("", false); repository = DocumentHelper.createDocument(); 302 Element rootNode = repository.addElement("repository"); processDir(rootNode, rootDir, null, 0, ISolutionRepository.ACTION_ADMIN); 304 } 305 306 private void processDir(Element parentNode, File parentDir, String solutionId, int pathIdx, int actionOperation) { 307 File files[] = parentDir.listFiles(); 308 for (int idx = 0; idx < files.length; idx++) { 310 if (!files[idx].isDirectory()) { 311 String fileName = files[idx].getName(); 312 if (fileName.equals("Entries") || fileName.equals("Repository") || fileName.equals("Root")) { continue; 315 } 316 String solutionPath = files[idx].getAbsolutePath().substring(rootPath.length()); 317 if (fileName.toLowerCase().endsWith(".url")) { addUrlToRepository(files[idx], parentNode, solutionPath); 319 } 320 if (!fileName.toLowerCase().endsWith(".xaction") && !fileName.toLowerCase().endsWith(".xml")) { continue; 323 } 324 if (fileName.toLowerCase().equals("index.xml")) { continue; 327 } 328 String path = files[idx].getAbsolutePath().substring(pathIdx); 329 if (!path.equals(fileName)) { 330 path = path.substring(0, path.length() - fileName.length() - 1); 331 path = path.replace('\\', '/'); 334 } else { 335 path = ""; } 337 if (fileName.toLowerCase().endsWith(".xaction")) { info(Messages.getString("SolutionRepository.DEBUG_ADDING_ACTION", fileName)); IActionSequence actionSequence = getActionSequence(solutionId, path, fileName, loggingLevel, actionOperation); 341 if (actionSequence == null) { 342 error(Messages.getErrorString("SolutionRepository.ERROR_0006_INVALID_SEQUENCE_DOCUMENT", fileName)); } else { 344 addToRepository(actionSequence, parentNode, files[idx]); 345 } 346 } 347 } 348 } 349 for (int idx = 0; idx < files.length; idx++) { 350 if (files[idx].isDirectory() && (!files[idx].getName().equalsIgnoreCase("system")) && (!files[idx].getName().equalsIgnoreCase("CVS")) && (!files[idx].getName().equalsIgnoreCase(".svn"))) { Element dirNode = parentNode.addElement("file"); dirNode.addAttribute("type", FileInfo.FILE_TYPE_FOLDER); String thisSolution; 355 String path = ""; if (solutionId == null) { 357 thisSolution = files[idx].getName(); 358 pathIdx = rootPath.length() + File.separator.length() + thisSolution.length(); 359 } else { 360 thisSolution = solutionId; 361 path = files[idx].getAbsolutePath().substring(pathIdx); 362 path = path.replace('\\', '/'); 365 dirNode.addElement("path").setText(path); } 367 File indexFile = new File (files[idx], "index.xml"); Document indexDoc = null; 369 if (indexFile.exists()) { 370 indexDoc = getSolutionDocument(thisSolution, path, "index.xml"); } 372 if (indexDoc != null) { 373 addIndexToRepository(indexDoc, files[idx], dirNode, path, thisSolution); 374 } else { 375 dirNode.addAttribute("visible", "false"); String dirName = files[idx].getName(); 377 dirNode.addAttribute("name", dirName); dirNode.addElement("title").setText(dirName); } 380 processDir(dirNode, files[idx], thisSolution, pathIdx, actionOperation); 381 } else if (solutionId == null && files[idx].getName().equalsIgnoreCase("index.xml")) { Document indexDoc = null; 383 indexDoc = getSolutionDocument("", "", "index.xml"); if (indexDoc != null) { 385 addIndexToRepository(indexDoc, files[idx], parentNode, "", ""); } 387 } 388 } 389 } 390 391 private void localizeDoc(Node document, File file) { 392 String fileName = file.getName(); 393 int dotIndex = fileName.indexOf('.'); 394 String baseName = fileName.substring(0, dotIndex); 395 try { 398 List nodes = document.selectNodes("descendant::*"); Iterator nodeIterator = nodes.iterator(); 400 while (nodeIterator.hasNext()) { 401 Node node = (Node) nodeIterator.next(); 402 String name = node.getText(); 403 if (name.startsWith("%") && !node.getPath().endsWith("/text()")) { try { 405 String localeText = getLocaleString(name, baseName, file); 406 if (localeText != null) { 407 node.setText(localeText); 408 } 409 } catch (Exception e) { 410 warn(Messages.getString("SolutionRepository.WARN_MISSING_RESOURCE_PROPERTY", name.substring(1), baseName, locale.toString())); } 412 } 413 } 414 } catch (Exception e) { 415 error(Messages.getErrorString("SolutionRepository.ERROR_0007_COULD_NOT_READ_PROPERTIES", file.getAbsolutePath()), e); } 417 } 418 419 private String getLocaleString(String key, String baseName, File baseFile) { 420 File searchDir = baseFile.getParentFile(); 421 try { 422 boolean searching = true; 423 while (searching) { 424 File test = new File (searchDir, baseName + '_' + locale.getLanguage() + '_' + locale.getCountry() + '_' + locale.getVariant() + ".properties"); if (!test.exists()) { 427 test = new File (searchDir, baseName + '_' + locale.getLanguage() + '_' + locale.getCountry() + ".properties"); } 429 if (!test.exists()) { 430 test = new File (searchDir, baseName + '_' + locale.getLanguage() + ".properties"); } 432 if (!test.exists()) { 433 test = new File (searchDir, baseName + ".properties"); } 435 if (test.exists()) { 436 437 Properties p = (Properties ) propertyMap.get(test.getCanonicalPath()); 438 if (p == null) { 439 p = new Properties (); 440 p.load(new FileInputStream (test)); 441 propertyMap.put(test.getCanonicalPath(), p); 442 } 443 444 String localeText = p.getProperty(key.substring(1)); 445 if (localeText != null) { 446 return localeText; 447 } 448 } 449 if (searching) { 450 if (!baseName.equals("messages")) { baseName = "messages"; } else { 453 if (searchDir.equals(rootFile)) { 454 searching = false; 455 } else { 456 searchDir = searchDir.getParentFile(); 457 } 458 } 459 } 460 } 461 return null; 462 } catch (Exception e) { 463 error(Messages.getErrorString("SolutionRepository.ERROR_0007_COULD_NOT_READ_PROPERTIES", baseFile.getAbsolutePath()), e); } 465 return null; 466 } 467 468 private void addIndexToRepository(Document indexDoc, File directoryFile, Element directoryNode, String path, String solution) { 469 String dirName = getValue(indexDoc, "/index/name", directoryFile.getName().replace('_', ' ')); String description = getValue(indexDoc, "/index/description", ""); String iconPath = getValue(indexDoc, "/index/icon", ""); String displayType = getValue(indexDoc, "/index/display-type", "icons"); boolean visible = getValue(indexDoc, "/index/visible", "false").equalsIgnoreCase("true"); if (solution == null) { 477 directoryNode.addAttribute("name", solution); } else { 479 directoryNode.addAttribute("name", directoryFile.getName()); } 481 directoryNode.addElement("title").setText(dirName); directoryNode.addAttribute("path", path); directoryNode.addElement("description").setText(description); if (iconPath != null && !iconPath.equals("")) { String rolloverIconPath = null; 487 int rolloverIndex = iconPath.indexOf("|"); if (rolloverIndex > -1) { 489 rolloverIconPath = iconPath.substring(rolloverIndex + 1); 490 iconPath = iconPath.substring(0, rolloverIndex); 491 } 492 if (publishIcon(PentahoSystem.getApplicationContext().getSolutionPath(solution + File.separator + path), iconPath)) { 493 directoryNode.addElement("icon").setText("getImage?image=icons/" + iconPath); } else { 495 directoryNode.addElement("icon").setText(iconPath); } 497 if (rolloverIconPath != null) { 498 if (publishIcon(PentahoSystem.getApplicationContext().getSolutionPath(solution + File.separator + path), rolloverIconPath)) { 499 directoryNode.addElement("rollovericon").setText("getImage?image=icons/" + rolloverIconPath); } else { 501 directoryNode.addElement("rollovericon").setText(rolloverIconPath); } 503 } 504 } 505 directoryNode.addAttribute("visible", Boolean.toString(visible)); directoryNode.addAttribute("displaytype", displayType); directoryNode.addElement("solution").setText(solution); } 509 510 private void addUrlToRepository(File file, Element parentNode, String solutionPath) { 511 ActionResource urlResource = new ActionResource(file.getName(), IActionResource.SOLUTION_FILE_RESOURCE, "text/url", solutionPath); try { 514 String urlContent = getResourceAsString(urlResource); 515 StringTokenizer tokenizer = new StringTokenizer (urlContent, "\n"); String url = null; 517 String title = file.getName(); 518 String description = null; 519 String iconPath = null; 520 String target = null; 521 while (tokenizer.hasMoreTokens()) { 522 String line = tokenizer.nextToken(); 523 int pos = line.indexOf('='); 524 if (pos > 0) { 525 String name = line.substring(0, pos); 526 String value = line.substring(pos + 1); 527 if ((value != null) && (value.length() > 0) && (value.charAt(value.length() - 1) == '\r')) { 528 value = value.substring(0, value.length() - 1); 529 } 530 if ("URL".equalsIgnoreCase(name)) { url = value; 532 } 533 if ("name".equalsIgnoreCase(name)) { title = value; 535 } 536 if ("description".equalsIgnoreCase(name)) { description = value; 538 } 539 if ("icon".equalsIgnoreCase(name)) { iconPath = value; 541 } 542 if ("target".equalsIgnoreCase(name)) { target = value; 544 } 545 } 546 } 547 if (url != null) { 548 Element dirNode = parentNode.addElement("file"); dirNode.addAttribute("type", FileInfo.FILE_TYPE_URL); dirNode.addElement("filename").setText(file.getName()); dirNode.addElement("title").setText(title); if (target != null) { 554 dirNode.addElement("target").setText(target); } 556 if (description != null) { 557 dirNode.addElement("description").setText(description); } 559 if (iconPath != null && !iconPath.equals("")) { String rolloverIconPath = null; 561 int rolloverIndex = iconPath.indexOf("|"); if (rolloverIndex > -1) { 563 rolloverIconPath = iconPath.substring(rolloverIndex + 1); 564 iconPath = iconPath.substring(0, rolloverIndex); 565 } 566 if (publishIcon(file.getParentFile().getAbsolutePath(), iconPath)) { 567 dirNode.addElement("icon").setText("getImage?image=icons/" + iconPath); } else { 569 dirNode.addElement("icon").setText(iconPath); } 571 if (rolloverIconPath != null) { 572 if (publishIcon(PentahoSystem.getApplicationContext().getSolutionPath(solutionPath), rolloverIconPath)) { 573 dirNode.addElement("rollovericon").setText("getImage?image=icons/" + rolloverIconPath); } else { 575 dirNode.addElement("rollovericon").setText(rolloverIconPath); } 577 } 578 } 579 dirNode.addElement("url").setText(url); dirNode.addAttribute("visible", "true"); dirNode.addAttribute("displaytype", FileInfo.FILE_DISPLAY_TYPE_URL); localizeDoc(dirNode, file); 583 } 584 } catch (IOException e) { 585 } 586 } 587 588 private void addToRepository(IActionSequence actionSequence, Element parentNode, File file) { 589 Element dirNode = parentNode.addElement("file"); dirNode.addAttribute("type", FileInfo.FILE_TYPE_ACTIVITY); if (actionSequence.getSequenceName() == null || actionSequence.getSolutionPath() == null || actionSequence.getSolutionName() == null) { 592 error(Messages.getString("SolutionRepository.ERROR_0008_ACTION_SEQUENCE_NAME_INVALID")); return; 594 } 595 dirNode.addElement("filename").setText(actionSequence.getSequenceName()); dirNode.addElement("path").setText(actionSequence.getSolutionPath()); dirNode.addElement("solution").setText(actionSequence.getSolutionName()); String title = actionSequence.getTitle(); 599 if (title == null) { 600 dirNode.addElement("title").setText(actionSequence.getSequenceName()); } else { 602 dirNode.addElement("title").setText(title); } 604 String description = actionSequence.getDescription(); 605 if (description == null) { 606 dirNode.addElement("description"); } else { 608 dirNode.addElement("description").setText(description); } 610 String author = actionSequence.getAuthor(); 611 if (author == null) { 612 dirNode.addElement("author"); } else { 614 dirNode.addElement("author").setText(author); } 616 String iconPath = actionSequence.getIcon(); 617 if (iconPath != null && !iconPath.equals("")) { String rolloverIconPath = null; 619 int rolloverIndex = iconPath.indexOf("|"); if (rolloverIndex > -1) { 621 rolloverIconPath = iconPath.substring(rolloverIndex + 1); 622 iconPath = iconPath.substring(0, rolloverIndex); 623 } 624 if (publishIcon(file.getParentFile().getAbsolutePath(), iconPath)) { 625 dirNode.addElement("icon").setText("getImage?image=icons/" + iconPath); } else { 627 dirNode.addElement("icon").setText(actionSequence.getIcon()); } 629 if (rolloverIconPath != null) { 630 if (publishIcon(PentahoSystem.getApplicationContext().getSolutionPath(actionSequence.getSolutionName() + File.separator + actionSequence.getSolutionPath()), rolloverIconPath)) { 631 dirNode.addElement("rollovericon").setText("getImage?image=icons/" + rolloverIconPath); } else { 633 dirNode.addElement("rollovericon").setText(rolloverIconPath); } 635 } 636 } 637 String displayType = actionSequence.getResultType(); 638 if ((displayType == null) || ("none".equalsIgnoreCase(displayType))) { dirNode.addAttribute("visible", "false"); } else { 642 dirNode.addAttribute("visible", "true"); dirNode.addAttribute("displaytype", displayType); } 645 } 646 647 private boolean publishIcon(String dirPath, String iconPath) { 648 File iconSource = new File (dirPath + File.separator + iconPath); 649 if (iconSource.exists()) { 650 File tmpDir = getFile("system/tmp/icons", true); tmpDir.mkdirs(); 652 File iconDestintation = new File (tmpDir.getAbsoluteFile() + File.separator + iconPath); 653 if (iconDestintation.exists()) { 654 iconDestintation.delete(); 655 } 656 try { 657 long size = iconSource.length(); 659 byte bytes[] = new byte[(int) size]; 660 FileInputStream stream = new FileInputStream (iconSource); 662 try { 663 FileOutputStream outputStream = new FileOutputStream (iconDestintation); 664 try { 665 stream.read(bytes); 666 outputStream.write(bytes); 667 outputStream.flush(); 668 } finally { 669 outputStream.close(); 670 } 671 } finally { 672 stream.close(); 673 } 674 } catch (FileNotFoundException e) { 675 } catch (IOException e) { 677 } 678 return true; 679 } else { 680 return false; 681 } 682 } 683 684 public Document getSolutions(int actionOperation) { 685 if (repository == null) { 686 publish(session, loggingLevel); 687 } 688 return repository; 689 } 690 691 public Document getActionSequences(String solution, String path, boolean subDirectories, boolean visibleOnly, int actionOperation) { 692 List nodes; 693 if (solution == null) { 694 nodes = getSolutionNames(); 695 } else { 696 nodes = getFileListIterator(solution, path, subDirectories, visibleOnly); 697 } 698 Document document = DocumentHelper.createDocument(); 699 Element root = document.addElement("files"); Element pathNames = root.addElement("location"); 702 pathNames.setText(getPathNames(solution, path)); 703 704 Iterator nodeIterator = nodes.iterator(); 705 while (nodeIterator.hasNext()) { 706 Node node = (Node) nodeIterator.next(); 707 root.add((Node) node.clone()); 708 } 709 return document; 710 } 711 712 public List getSolutionNames() { 713 String xPath = "/repository/file"; if (repository == null) { 718 publish(session, loggingLevel); 719 } 720 return repository.selectNodes(xPath); 721 } 722 723 private String getPathNames(String solutionId, String path) { 724 if (repository == null) { 725 publish(session, loggingLevel); 726 } 727 if (solutionId == null) { 728 return ""; } 730 731 String xPath = "/repository/file[@type='" + FileInfo.FILE_TYPE_FOLDER + "'][@name='" + solutionId + "']"; 733 if (path != null) { 734 String folders[] = path.split("/"); if (folders != null) { 736 for (int idx = 0; idx < folders.length; idx++) { 737 xPath += "/file[@type='" + FileInfo.FILE_TYPE_FOLDER + "'][@name='" + folders[idx] + "']"; xPath += "[@visible='true']"; } 740 } 741 } 742 743 StringBuffer sb = new StringBuffer (); 744 List list = repository.selectNodes(xPath); 745 if (list != null && list.size() > 0) { 746 Element node = (Element) list.get(0); 748 boolean done = false; 750 while (node != null && !done) { 751 Node titleNode = node.selectSingleNode("title"); if (titleNode != null) { 753 String name = titleNode.getText(); 754 sb.insert(0, name + "/"); } else { 756 done = true; 758 } 759 node = node.getParent(); 760 } 761 } 762 return sb.toString(); 763 764 } 765 766 private List getFileListIterator(String solutionId, String path, boolean subDirectories, boolean visibleOnly) { 767 if (repository == null) { 768 publish(session, loggingLevel); 769 } 770 String xPath; 771 if (solutionId == null) { 772 xPath = "/repository/file[@type='" + FileInfo.FILE_TYPE_FOLDER + "']"; } else { 774 xPath = "/repository/file[@type='" + FileInfo.FILE_TYPE_FOLDER + "'][@name='" + solutionId + "']"; } 776 if (path != null) { 777 String folders[] = path.split("/"); if (folders != null) { 779 for (int idx = 0; idx < folders.length; idx++) { 780 xPath += "/file[@type='" + FileInfo.FILE_TYPE_FOLDER + "'][@name='" + folders[idx] + "']"; if (visibleOnly) { 782 xPath += "[@visible='true']"; } 784 } 785 } 786 } 787 if (subDirectories) { 788 xPath = "descendant-or-self::" + xPath; } 790 if (debug) 791 debug(Messages.getString("SolutionRepository.DEBUG_FILE_LIST_XPATH", xPath)); return repository.selectNodes(xPath); 793 } 794 795 public String getValue(Document doc, String xPath, String defaultValue) { 796 if (doc != null) { 797 Node node = doc.selectSingleNode(xPath); 798 if (node == null) { 799 return defaultValue; 800 } 801 return node.getText(); 802 } 803 return defaultValue; 804 } 805 806 public Document getSolutionStructure(int actionOperation) { 807 Document document = DocumentHelper.createDocument(); 808 File rootDir = getFile(EMPTY_STR, false); 809 Element root = document.addElement(ROOT_NODE_NAME).addAttribute(LOCATION_ATTR_NAME, rootDir.getAbsolutePath()); 810 processSolutionTree(root, rootDir); 811 return document; 812 } 813 814 public Document getSolutionTree(int actionOperation) { 815 return (SolutionReposUtil.getActionSequences(new FileSolutionFile(rootFile, rootFile), actionOperation)); 816 } 817 818 private void processSolutionTree(Element parentNode, File targetFile) { 819 if (targetFile.isDirectory()) { 820 if (!SolutionReposUtil.ignoreDirectory(targetFile.getName())) { 821 Element childNode = parentNode.addElement(ENTRY_NODE_NAME).addAttribute(TYPE_ATTR_NAME, DIRECTORY_ATTR).addAttribute(NAME_ATTR_NAME, targetFile.getName()); 822 File files[] = targetFile.listFiles(); 823 for (int i = 0; i < files.length; i++) { 824 File file = files[i]; 825 processSolutionTree(childNode, file); 826 } 827 } 828 } else { 829 if (!targetFile.isHidden() && !SolutionReposUtil.ignoreFile(targetFile.getName())) { 830 parentNode.addElement(ENTRY_NODE_NAME).addAttribute(TYPE_ATTR_NAME, FILE_ATTR).addAttribute(NAME_ATTR_NAME, targetFile.getName()); 831 } 832 } 833 } 834 835 public InputStream getSolutionFileData(String repositoryRoot, String solutionName, String filePath, String fileName) { 836 File solutionFile = new File (repositoryRoot + File.pathSeparator + solutionName + File.pathSeparator + filePath + File.pathSeparator + fileName); 837 if (solutionFile.exists()) { 838 try { 839 InputStream is = new FileInputStream (solutionFile); 840 return is; 841 } catch (FileNotFoundException e) { 842 e.printStackTrace(); 844 } 845 } 846 return null; 847 } 848 849 public boolean resourceExists(String solutionPath) { 852 String filePath = PentahoSystem.getApplicationContext().getSolutionPath(solutionPath); 853 File file = new File (filePath); 854 return file.exists(); 855 } 856 857 public long resourceSize(String solutionPath) { 858 if (!resourceExists(solutionPath)) { 859 return -1; 860 } 861 String filePath = PentahoSystem.getApplicationContext().getSolutionPath(solutionPath); 862 File file = new File (filePath); 863 return file.length(); 864 } 865 866 public InputStream getResourceInputStream(IActionResource actionResource) { 867 int resourceSource = actionResource.getSourceType(); 868 String realPath = null; 869 if (resourceSource == IActionResource.URL_RESOURCE) { 870 return HttpUtil.getURLInputStream(actionResource.getAddress()); 871 } else if (resourceSource == IActionResource.UNKNOWN_RESOURCE) { 872 return null; 873 } else if (resourceSource == IActionResource.SOLUTION_FILE_RESOURCE) { 874 realPath = PentahoSystem.getApplicationContext().getSolutionPath(actionResource.getAddress()); 875 } else if (resourceSource == IActionResource.FILE_RESOURCE) { 876 realPath = actionResource.getAddress(); 877 } 878 File file = new File (realPath); 879 file = getLocalizedFile(file); 880 if (!file.exists()) { 881 error(Messages.getErrorString("SOLREPO.ERROR_0006_MISSING_RESOURCE", realPath)); return null; 883 } 884 try { 885 FileInputStream inputStream = new FileInputStream (file); 886 return inputStream; 887 } catch (FileNotFoundException e) { 888 error(Messages.getErrorString("SOLREPO.ERROR_0006_MISSING_RESOURCE", realPath)); } 890 return null; 891 } 892 893 public InputStream getResourceInputStream(String solutionPath) { 894 ActionResource resource = new ActionResource("", IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", solutionPath); 896 return getResourceInputStream(resource); 897 } 898 899 public Reader getResourceReader(IActionResource actionResource) throws FileNotFoundException , IOException { 900 int resourceSource = actionResource.getSourceType(); 902 String realPath = null; 903 if (resourceSource == IActionResource.URL_RESOURCE) { 904 return HttpUtil.getURLReader(actionResource.getAddress()); 905 } else if (resourceSource == IActionResource.UNKNOWN_RESOURCE) { 906 return null; 907 } else if (resourceSource == IActionResource.SOLUTION_FILE_RESOURCE) { 908 realPath = PentahoSystem.getApplicationContext().getSolutionPath(actionResource.getAddress()); 909 } else if (resourceSource == IActionResource.FILE_RESOURCE) { 910 realPath = actionResource.getAddress(); 911 } 912 File file = new File (realPath); 913 file = getLocalizedFile(file); 914 if (!file.exists()) { 915 error(Messages.getErrorString("SOLREPO.ERROR_0006_MISSING_RESOURCE", realPath)); return null; 917 } 918 FileInputStream fin = new FileInputStream (file); 920 InputStreamReader reader = new InputStreamReader (fin, LocaleHelper.getSystemEncoding()); 921 return reader; 922 } 923 924 public Reader getResourceReader(String solutionPath) throws FileNotFoundException , IOException { 925 ActionResource resource = new ActionResource("", IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", solutionPath); 927 return getResourceReader(resource); 928 } 929 930 public String getResourceAsString(IActionResource actionResource) throws IOException { 931 StringBuffer buffer = new StringBuffer (); 933 Reader reader = getResourceReader(actionResource); 934 if (reader == null) { 935 return null; 936 } 937 try { 938 char chars[] = new char[1024]; 939 int charsRead = reader.read(chars); 940 while (charsRead > 0) { 941 buffer.append(chars, 0, charsRead); 942 charsRead = reader.read(chars); 943 } 944 return buffer.toString(); 945 } finally { 946 reader.close(); 947 } 948 } 949 950 public String getResourceAsString(String solutionPath) throws IOException { 951 ActionResource resource = new ActionResource("", IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", solutionPath); 953 return getResourceAsString(resource); 954 } 955 956 protected File getLocalizedFile(File resourceFile) { 957 String fileName = resourceFile.getName(); 959 int idx = fileName.indexOf('.'); 960 String baseName = fileName.substring(0, idx); 961 String extension = fileName.substring(idx); 962 File directory = resourceFile.getParentFile(); 963 String language = locale.getLanguage(); 964 String country = locale.getCountry(); 965 String variant = locale.getVariant(); 966 File localeFile = null; 967 if (!variant.equals("")) { localeFile = new File (directory, baseName + "_" + language + "_" + country + "_" + variant + extension); } 970 if (localeFile == null || !localeFile.exists()) { 971 localeFile = new File (directory, baseName + "_" + language + "_" + country + extension); } 973 if (!localeFile.exists()) { 974 localeFile = new File (directory, baseName + "_" + language + extension); } 976 if (!localeFile.exists()) { 977 localeFile = new File (directory, baseName + extension); 978 } 979 if (localeFile.exists()) { 980 return localeFile; 981 } else { 982 return resourceFile; 983 } 984 } 985 986 public DataSource getResourceDataSource(String solutionPath) { 987 ActionResource resource = new ActionResource("", IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", solutionPath); 989 return getResourceDataSource(resource); 990 } 991 992 public DataSource getResourceDataSource(IActionResource actionResource) { 993 int resourceSource = actionResource.getSourceType(); 995 String realPath = null; 996 if (resourceSource == IActionResource.URL_RESOURCE) { 997 try { 998 URL url = new URL (actionResource.getAddress()); 999 return (new URLDataSource (url)); 1000 } catch (Throwable t) { 1001 return (null); 1002 } 1003 } else if (resourceSource == IActionResource.UNKNOWN_RESOURCE) { 1004 return null; 1005 } else if (resourceSource == IActionResource.SOLUTION_FILE_RESOURCE) { 1006 realPath = PentahoSystem.getApplicationContext().getSolutionPath(actionResource.getAddress()); 1007 } else if (resourceSource == IActionResource.FILE_RESOURCE) { 1008 realPath = actionResource.getAddress(); 1009 } 1010 File file = new File (realPath); 1011 file = getLocalizedFile(file); 1012 if (!file.exists()) { 1013 return null; 1014 } 1015 return (new FileDataSource (file)); 1016 } 1017 1018 public Document getResourceAsDocument(String solutionPath) throws IOException { 1019 ActionResource resource = new ActionResource("", IActionResource.SOLUTION_FILE_RESOURCE, "text/xml", solutionPath); 1021 return getResourceAsDocument(resource); 1022 } 1023 1024 public Document getResourceAsDocument(IActionResource actionResource) throws IOException { 1025 String xml = getResourceAsString(actionResource); 1027 if (xml == null) { 1028 return null; 1029 } else { 1030 return XmlHelper.getDocFromString(xml); 1031 } 1032 } 1033 1034 public boolean removeSolutionFile(String solution, String path, String fileName) { 1035 String filePath = solution + path + fileName; 1036 File deleteFile = new File (filePath); 1037 if (deleteFile.exists()) { 1038 if (!deleteFile.isDirectory()) { 1039 return deleteFile.delete(); 1040 } else { return deleteFolder(deleteFile); 1043 } 1044 } 1045 return false; 1046 } 1047 1048 private boolean deleteFolder(File dir) { 1049 if (!dir.isDirectory()) { 1050 logger.warn(Messages.getString("SolutionRepository.USER_DELETE_FOLDER_WARNING")); return false; 1052 } 1053 String [] files = dir.list(); 1054 for (int i = 0; i < files.length; i++) { 1055 File file = new File (dir.getAbsolutePath() + File.separator + files[i]); 1056 if (file.isDirectory()) { 1057 deleteFolder(file); 1058 } else { 1059 file.delete(); 1060 } 1061 } 1062 return dir.delete(); 1063 } 1064 1065 public int addSolutionFile(String baseUrl, String path, String fileName, File f, boolean overwrite) { 1066 File fNew = new File (baseUrl + path + fileName); 1067 1068 int status = ISolutionRepository.FILE_ADD_SUCCESSFUL; 1069 1070 if (fNew.exists() && !overwrite) { 1071 status = ISolutionRepository.FILE_EXISTS; 1072 } else { 1073 FileChannel in = null, out = null; 1074 try { 1075 in = new FileInputStream (f).getChannel(); 1076 out = new FileOutputStream (fNew).getChannel(); 1077 out.transferFrom(in, 0, in.size()); 1078 } catch (Exception e) { 1079 logger.error(e.toString()); 1080 status = ISolutionRepository.FILE_ADD_FAILED; 1081 } finally { 1082 try { 1083 if (in != null) 1084 in.close(); 1085 if (out != null) 1086 out.close(); 1087 } catch (Exception e) { 1088 } 1089 } 1090 } 1091 return status; 1092 } 1093 1094 public int addSolutionFile(String baseUrl, String path, String fileName, byte[] data, boolean overwrite) { 1095 File fNew = new File (baseUrl + path + fileName); 1097 int status = ISolutionRepository.FILE_ADD_SUCCESSFUL; 1098 if (fNew.exists() && !overwrite) { 1099 status = ISolutionRepository.FILE_EXISTS; 1100 } else { 1101 FileOutputStream fNewOut = null; 1102 try { 1103 fNewOut = new FileOutputStream (fNew); 1104 fNewOut.write(data); 1105 } catch (Exception e) { 1106 status = ISolutionRepository.FILE_ADD_FAILED; 1107 logger.error(e.toString()); 1108 } finally { 1109 try { 1110 fNewOut.close(); 1111 } catch (Exception e) { 1112 } 1113 } 1114 } 1115 return status; 1116 } 1117 1118 public Document getSolutions(String solutionName, String pathName, int actionOperation) { 1119 return getSolutions(actionOperation); 1120 } 1121 1122 public String [] getAllActionSequences() { 1123 File rootDir = getFile("", false); List files = new ArrayList (); 1125 files = getAllActionSequences(rootDir, files); 1126 String [] value = new String [files.size()]; 1127 Iterator iter = files.iterator(); 1128 int i = 0; 1129 int solutionPathOffset = PentahoSystem.getApplicationContext().getSolutionPath("").length(); while (iter.hasNext()) { 1131 File file = (File ) iter.next(); 1132 String filePath = file.getAbsolutePath(); 1133 filePath = filePath.substring(solutionPathOffset); 1134 filePath = filePath.replace('\\', '/'); 1135 value[i++] = filePath; 1136 } 1137 return value; 1138 } 1139 1140 private List getAllActionSequences(File rootDir, List files) { 1141 if (!rootDir.isDirectory()) { 1142 return files; 1143 } 1144 File [] fileArray = rootDir.listFiles(new xActionFileFilter()); 1145 for (int i = 0; i < fileArray.length; i++) { 1146 files.add(fileArray[i]); 1147 } 1148 fileArray = rootDir.listFiles(); 1149 for (int i = 0; i < fileArray.length; i++) { 1150 if (fileArray[i].isDirectory()) { 1151 getAllActionSequences(fileArray[i], files); 1152 } 1153 } 1154 return files; 1155 } 1156 1157 public long getSolutionFileLastModified(String path) { 1158 File file = getFile(path, false); 1159 long mod = -1; 1160 if (file != null) { 1161 mod = file.lastModified(); 1162 } 1163 return mod; 1164 } 1165 1166 class xActionFileFilter implements FilenameFilter { 1167 public boolean accept(File dir, String name) { 1168 int seperatorIndex = name.lastIndexOf('.'); 1169 if (seperatorIndex != -1) { 1170 return name.substring(name.lastIndexOf('.')).equalsIgnoreCase(".xaction"); } 1172 return false; 1173 } 1174 } 1175 1176} 1177 | Popular Tags |