0001: /*
0002: * File : $Source: /usr/local/cvs/opencms/src-modules/org/opencms/workplace/tools/database/CmsHtmlImport.java,v $
0003: * Date : $Date: 2008-02-27 12:05:51 $
0004: * Version: $Revision: 1.20 $
0005: *
0006: * This library is part of OpenCms -
0007: * the Open Source Content Management System
0008: *
0009: * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
0010: *
0011: * This library is free software; you can redistribute it and/or
0012: * modify it under the terms of the GNU Lesser General Public
0013: * License as published by the Free Software Foundation; either
0014: * version 2.1 of the License, or (at your option) any later version.
0015: *
0016: * This library is distributed in the hope that it will be useful,
0017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019: * Lesser General Public License for more details.
0020: *
0021: * For further information about Alkacon Software GmbH, please see the
0022: * company website: http://www.alkacon.com
0023: *
0024: * For further information about OpenCms, please see the
0025: * project website: http://www.opencms.org
0026: *
0027: * You should have received a copy of the GNU Lesser General Public
0028: * License along with this library; if not, write to the Free Software
0029: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0030: */
0031:
0032: package org.opencms.workplace.tools.database;
0033:
0034: import org.opencms.db.CmsDbIoException;
0035: import org.opencms.file.CmsFolder;
0036: import org.opencms.file.CmsObject;
0037: import org.opencms.file.CmsProperty;
0038: import org.opencms.file.CmsPropertyDefinition;
0039: import org.opencms.file.CmsResource;
0040: import org.opencms.file.CmsResourceFilter;
0041: import org.opencms.file.types.CmsResourceTypeFolder;
0042: import org.opencms.file.types.CmsResourceTypeImage;
0043: import org.opencms.file.types.CmsResourceTypePlain;
0044: import org.opencms.file.types.CmsResourceTypePointer;
0045: import org.opencms.file.types.CmsResourceTypeXmlPage;
0046: import org.opencms.i18n.CmsEncoder;
0047: import org.opencms.i18n.CmsMessageContainer;
0048: import org.opencms.importexport.CmsImportExportException;
0049: import org.opencms.loader.CmsResourceManager;
0050: import org.opencms.lock.CmsLock;
0051: import org.opencms.lock.CmsLockType;
0052: import org.opencms.main.CmsException;
0053: import org.opencms.main.CmsIllegalArgumentException;
0054: import org.opencms.main.CmsLog;
0055: import org.opencms.main.OpenCms;
0056: import org.opencms.relations.CmsLink;
0057: import org.opencms.report.I_CmsReport;
0058: import org.opencms.staticexport.CmsLinkTable;
0059: import org.opencms.util.CmsFileUtil;
0060: import org.opencms.util.CmsStringUtil;
0061: import org.opencms.xml.page.CmsXmlPage;
0062:
0063: import java.io.File;
0064: import java.io.FileInputStream;
0065: import java.io.FileOutputStream;
0066: import java.io.IOException;
0067: import java.io.InputStream;
0068: import java.net.MalformedURLException;
0069: import java.net.URL;
0070: import java.util.ArrayList;
0071: import java.util.Enumeration;
0072: import java.util.HashMap;
0073: import java.util.HashSet;
0074: import java.util.Hashtable;
0075: import java.util.Iterator;
0076: import java.util.List;
0077: import java.util.Locale;
0078: import java.util.Map;
0079: import java.util.StringTokenizer;
0080: import java.util.zip.ZipEntry;
0081: import java.util.zip.ZipInputStream;
0082:
0083: import org.apache.commons.collections.ExtendedProperties;
0084: import org.apache.commons.fileupload.FileItem;
0085: import org.apache.commons.logging.Log;
0086:
0087: /**
0088: * This class implements the HTML->OpenCms Template converter for OpenCms 6.x.<p>
0089: *
0090: * The HTML files can lay in a directory or in a zip file. The entries in the zip file
0091: * are saved temporary in the tmp-directory of the system. Every file is stored into the
0092: * correct location in the OpenCms VFS.<p>
0093: *
0094: *
0095: * @author Michael Emmerich
0096: * @author Armen Markarian
0097: * @author Peter Bonrad
0098: * @author Anja Röttgers
0099: *
0100: * @version $Revision: 1.20 $
0101: *
0102: * @since 6.0.0
0103: */
0104: public class CmsHtmlImport {
0105:
0106: /** filename of the meta.properties file. */
0107: public static final String META_PROPERTIES = "meta.properties";
0108:
0109: /** The log object for this class. */
0110: private static final Log LOG = CmsLog.getLog(CmsHtmlImport.class);
0111:
0112: /**
0113: * This function creates a folder in the temporary-directory.<p>
0114: *
0115: * @param name the name of the folder
0116: *
0117: * @return the folder file
0118: *
0119: * @throws Exception if the folder can not create
0120: */
0121: public static File createTempFolder(String name) throws Exception {
0122:
0123: File folder = null;
0124: folder = File.createTempFile(name, "", null);
0125: folder.delete();
0126: folder.mkdirs();
0127: folder.deleteOnExit();
0128: return folder;
0129: }
0130:
0131: /** the CmsObject to use. */
0132: private CmsObject m_cmsObject;
0133:
0134: /** the destination directory in the OpenCms VFS. */
0135: private String m_destinationDir;
0136:
0137: /** the download gallery name. */
0138: private String m_downloadGallery;
0139:
0140: /** the element name of the template. */
0141: private String m_element;
0142:
0143: /** the end pattern for extracting content. */
0144: private String m_endPattern;
0145:
0146: /** HashMap of all known extensions in OpenCms. */
0147: private Map m_extensions;
0148:
0149: /** Storage for external links. */
0150: private HashSet m_externalLinks;
0151:
0152: /** The file index contains all resource names in the real file system and their renamed ones in the OpenCms VFS. */
0153: private HashMap m_fileIndex;
0154:
0155: /** the HTML converter to parse and modify the content. */
0156: private CmsHtmlImportConverter m_htmlConverter;
0157:
0158: /** the path of the import temporary file in the "real" file system.*/
0159: private String m_httpDir;
0160:
0161: /** the image gallery name. */
0162: private String m_imageGallery;
0163:
0164: /** Storage for image alt tags, it is filled by the HtmlConverter each time a new image is found. */
0165: private HashMap m_imageInfo;
0166:
0167: /** the input directory in the "real" file system. */
0168: private String m_inputDir;
0169:
0170: /** the encoding used for all imported input files. */
0171: private String m_inputEncoding;
0172:
0173: /** should broken links be kept. */
0174: private boolean m_keepBrokenLinks;
0175:
0176: /** the external link gallery name. */
0177: private String m_linkGallery;
0178:
0179: /** the local use for content definition. */
0180: private String m_locale;
0181:
0182: /** the overwrite value new resources. */
0183: private boolean m_overwrite;
0184:
0185: /** Map with all parents in file system to OpenCms. */
0186: private HashMap m_parents;
0187:
0188: /** the report for the output. */
0189: private I_CmsReport m_report;
0190:
0191: /** the start pattern for extracting content. */
0192: private String m_startPattern;
0193:
0194: /** the template use for all pages. */
0195: private String m_template;
0196:
0197: /**
0198: * Default Constructor.<p>
0199: */
0200: public CmsHtmlImport() {
0201:
0202: m_overwrite = true;
0203: m_extensions = OpenCms.getResourceManager()
0204: .getExtensionMapping();
0205: m_fileIndex = new HashMap();
0206: m_parents = new HashMap();
0207: m_imageInfo = new HashMap();
0208: m_externalLinks = new HashSet();
0209: m_htmlConverter = new CmsHtmlImportConverter(this , false);
0210: }
0211:
0212: /**
0213: * Creates a new import object for the given cms object.<p>
0214: *
0215: * @param cms the current cms context
0216: */
0217: public CmsHtmlImport(CmsObject cms) {
0218:
0219: this ();
0220: m_cmsObject = cms;
0221: }
0222:
0223: /**
0224: * Calculates an absolute uri from a relative "uri" and the given absolute "baseUri".<p>
0225: *
0226: * If "uri" is already absolute, it is returned unchanged.
0227: * This method also returns "uri" unchanged if it is not well-formed.<p>
0228: *
0229: * @param relativeUri the relative uri to calculate an absolute uri for
0230: * @param baseUri the base uri, this must be an absolute uri
0231: * @return an absolute uri calculated from "uri" and "baseUri"
0232: */
0233: public String getAbsoluteUri(String relativeUri, String baseUri) {
0234:
0235: if ((relativeUri == null) || (relativeUri.charAt(0) == '/')
0236: || (relativeUri.startsWith("#"))) {
0237:
0238: return relativeUri;
0239: }
0240:
0241: // if we are on a windows system, we must add a ":" in the uri later
0242: String windowsAddition = "";
0243: if (File.separator.equals("\\")) {
0244: windowsAddition = ":";
0245: }
0246:
0247: try {
0248: URL baseUrl = new URL("file://");
0249: URL url = new URL(new URL(baseUrl, "file://" + baseUri),
0250: relativeUri);
0251: if (url.getQuery() == null) {
0252: if (url.getRef() == null) {
0253: return url.getHost() + windowsAddition
0254: + url.getPath();
0255: } else {
0256: return url.getHost() + windowsAddition
0257: + url.getPath() + "#" + url.getRef();
0258: }
0259: } else {
0260: return url.getHost() + windowsAddition + url.getPath()
0261: + "?" + url.getQuery();
0262: }
0263: } catch (MalformedURLException e) {
0264: return relativeUri;
0265: }
0266: }
0267:
0268: /**
0269: * Returns the destinationDir.<p>
0270: *
0271: * @return the destinationDir
0272: */
0273: public String getDestinationDir() {
0274:
0275: return m_destinationDir;
0276: }
0277:
0278: /**
0279: * Returns the downloadGallery.<p>
0280: *
0281: * @return the downloadGallery
0282: */
0283: public String getDownloadGallery() {
0284:
0285: return m_downloadGallery;
0286: }
0287:
0288: /**
0289: * Returns the element.<p>
0290: *
0291: * @return the element
0292: */
0293: public String getElement() {
0294:
0295: return m_element;
0296: }
0297:
0298: /**
0299: * Returns the endPattern.<p>
0300: *
0301: * @return the endPattern
0302: */
0303: public String getEndPattern() {
0304:
0305: return m_endPattern;
0306: }
0307:
0308: /**
0309: * Returns the httpDir.<p>
0310: *
0311: * @return the httpDir
0312: */
0313: public String getHttpDir() {
0314:
0315: return m_httpDir;
0316: }
0317:
0318: /**
0319: * Returns the imageGallery.<p>
0320: *
0321: * @return the imageGallery
0322: */
0323: public String getImageGallery() {
0324:
0325: return m_imageGallery;
0326: }
0327:
0328: /**
0329: * Returns the inputDir.<p>
0330: *
0331: * @return the inputDir
0332: */
0333: public String getInputDir() {
0334:
0335: return m_inputDir;
0336: }
0337:
0338: /**
0339: * Returns the inputEncoding.<p>
0340: *
0341: * @return the inputEncoding
0342: */
0343: public String getInputEncoding() {
0344:
0345: return m_inputEncoding;
0346: }
0347:
0348: /**
0349: * Returns the linkGallery.<p>
0350: *
0351: * @return the linkGallery
0352: */
0353: public String getLinkGallery() {
0354:
0355: return m_linkGallery;
0356: }
0357:
0358: /**
0359: * Returns the local.<p>
0360: *
0361: * @return the local
0362: */
0363: public String getLocale() {
0364:
0365: return m_locale;
0366: }
0367:
0368: /**
0369: * Returns the startPattern.<p>
0370: *
0371: * @return the startPattern
0372: */
0373: public String getStartPattern() {
0374:
0375: return m_startPattern;
0376: }
0377:
0378: /**
0379: * Returns the template.<p>
0380: *
0381: * @return the template
0382: */
0383: public String getTemplate() {
0384:
0385: return m_template;
0386: }
0387:
0388: /**
0389: * Returns the keepBrokenLinks.<p>
0390: *
0391: * @return the keepBrokenLinks
0392: */
0393: public boolean isKeepBrokenLinks() {
0394:
0395: return m_keepBrokenLinks;
0396: }
0397:
0398: /**
0399: * Returns the overwrite.<p>
0400: *
0401: * @return the overwrite
0402: */
0403: public boolean isOverwrite() {
0404:
0405: return m_overwrite;
0406: }
0407:
0408: /**
0409: * Sets the cmsObject.<p>
0410: *
0411: * @param cmsObject the cmsObject to set
0412: */
0413: public void setCmsObject(CmsObject cmsObject) {
0414:
0415: m_cmsObject = cmsObject;
0416: }
0417:
0418: /**
0419: * Sets the destinationDir.<p>
0420: *
0421: * @param destinationDir the destinationDir to set
0422: */
0423: public void setDestinationDir(String destinationDir) {
0424:
0425: m_destinationDir = destinationDir;
0426: }
0427:
0428: /**
0429: * Sets the downloadGallery.<p>
0430: *
0431: * @param downloadGallery the downloadGallery to set
0432: */
0433: public void setDownloadGallery(String downloadGallery) {
0434:
0435: m_downloadGallery = downloadGallery;
0436: }
0437:
0438: /**
0439: * Sets the element.<p>
0440: *
0441: * @param element the element to set
0442: */
0443: public void setElement(String element) {
0444:
0445: m_element = element;
0446: }
0447:
0448: /**
0449: * Sets the endPattern.<p>
0450: *
0451: * @param endPattern the endPattern to set
0452: */
0453: public void setEndPattern(String endPattern) {
0454:
0455: m_endPattern = endPattern;
0456: }
0457:
0458: /**
0459: * Sets the httpDir.<p>
0460: *
0461: * @param httpDir the httpDir to set
0462: */
0463: public void setHttpDir(String httpDir) {
0464:
0465: m_httpDir = httpDir;
0466: }
0467:
0468: /**
0469: * Sets the imageGallery.<p>
0470: *
0471: * @param imageGallery the imageGallery to set
0472: */
0473: public void setImageGallery(String imageGallery) {
0474:
0475: m_imageGallery = imageGallery;
0476: }
0477:
0478: /**
0479: * Sets the inputDir.<p>
0480: *
0481: * @param inputDir the inputDir to set
0482: */
0483: public void setInputDir(String inputDir) {
0484:
0485: m_inputDir = inputDir;
0486: }
0487:
0488: /**
0489: * Sets the inputEncoding.<p>
0490: *
0491: * @param inputEncoding the inputEncoding to set
0492: */
0493: public void setInputEncoding(String inputEncoding) {
0494:
0495: m_inputEncoding = inputEncoding;
0496: }
0497:
0498: /**
0499: * Sets the keepBrokenLinks.<p>
0500: *
0501: * @param keepBrokenLinks the keepBrokenLinks to set
0502: */
0503: public void setKeepBrokenLinks(boolean keepBrokenLinks) {
0504:
0505: m_keepBrokenLinks = keepBrokenLinks;
0506: }
0507:
0508: /**
0509: * Sets the linkGallery.<p>
0510: *
0511: * @param linkGallery the linkGallery to set
0512: */
0513: public void setLinkGallery(String linkGallery) {
0514:
0515: m_linkGallery = linkGallery;
0516: }
0517:
0518: /**
0519: * Sets the local.<p>
0520: *
0521: * @param locale the local to set
0522: */
0523: public void setLocale(String locale) {
0524:
0525: m_locale = locale;
0526: }
0527:
0528: /**
0529: * Sets the overwrite.<p>
0530: *
0531: * @param overwrite the overwrite to set
0532: */
0533: public void setOverwrite(boolean overwrite) {
0534:
0535: m_overwrite = overwrite;
0536: }
0537:
0538: /**
0539: * Sets the startPattern.<p>
0540: *
0541: * @param startPattern the startPattern to set
0542: */
0543: public void setStartPattern(String startPattern) {
0544:
0545: m_startPattern = startPattern;
0546: }
0547:
0548: /**
0549: * Sets the template.<p>
0550: *
0551: * @param template the template to set
0552: */
0553: public void setTemplate(String template) {
0554:
0555: m_template = template;
0556: }
0557:
0558: /**
0559: * Imports all resources from the real file system, stores them into the correct locations
0560: * in the OpenCms VFS and modifies all links. This method is called form the JSP to start the
0561: * import process.<p>
0562: *
0563: * @param report StringBuffer for reporting
0564: *
0565: * @throws Exception if something goes wrong
0566: */
0567: public void startImport(I_CmsReport report) throws Exception {
0568:
0569: try {
0570: m_report = report;
0571: m_report.println(Messages.get().container(
0572: Messages.RPT_HTML_IMPORT_BEGIN_0),
0573: I_CmsReport.FORMAT_HEADLINE);
0574:
0575: boolean isStream = !CmsStringUtil
0576: .isEmptyOrWhitespaceOnly(m_httpDir);
0577: File streamFolder = null;
0578: if (isStream) {
0579: // the input is starting through the HTTP upload
0580: streamFolder = unzipStream();
0581: m_inputDir = streamFolder.getAbsolutePath();
0582: }
0583:
0584: // first build the index of all resources
0585: buildIndex(m_inputDir);
0586: // build list with all parent resources of input directory for links to outside import folder
0587: buildParentPath();
0588: // copy and parse all HTML files first. during the copy process we will collect all
0589: // required data for downloads and images
0590: copyHtmlFiles(m_inputDir);
0591: // now copy the other files
0592: copyOtherFiles(m_inputDir);
0593: // finally create all the external links
0594: createExternalLinks();
0595:
0596: if (isStream && streamFolder != null) {
0597: m_report.println(Messages.get().container(
0598: Messages.RPT_HTML_DELETE_0),
0599: I_CmsReport.FORMAT_NOTE);
0600: // delete the files of the zip file
0601: CmsFileUtil.purgeDirectory(streamFolder);
0602: // deletes the zip file
0603: File file = new File(m_httpDir);
0604: if (file.exists() && file.canWrite()) {
0605: file.delete();
0606: }
0607: }
0608: m_report.println(Messages.get().container(
0609: Messages.RPT_HTML_IMPORT_END_0),
0610: I_CmsReport.FORMAT_HEADLINE);
0611: } catch (Exception e) {
0612: e.printStackTrace();
0613: }
0614: }
0615:
0616: /**
0617: * Add a new external link to the storage of external links.<p>
0618: *
0619: * All links in this storage are later used to create entries in the external link gallery.<p>
0620: *
0621: * @param externalLink link to an external resource
0622: *
0623: * @return the complete path to the external link file, if one is created.
0624: */
0625: public String storeExternalLink(String externalLink) {
0626:
0627: if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_linkGallery)) {
0628: m_externalLinks.add(externalLink);
0629: return getExternalLinkFile(externalLink);
0630: }
0631:
0632: return null;
0633: }
0634:
0635: /**
0636: * Add a new image info to the storage of image info's.<p>
0637: *
0638: * The image info's are later used to set the description properties of the images.<p>
0639: *
0640: * @param image the name of the image
0641: * @param altText the alt-text of the image
0642: */
0643: public void storeImageInfo(String image, String altText) {
0644:
0645: m_imageInfo.put(image, altText);
0646: }
0647:
0648: /**
0649: * Translated a link into the real file system to its new location in the OpenCms VFS.<p>
0650: *
0651: * This is needed by the HtmlConverter to get the correct links for link translation.<p>
0652: *
0653: * @param link link to the real file system
0654: *
0655: * @return string containing absolute link into the OpenCms VFS
0656: */
0657: public String translateLink(String link) {
0658:
0659: String translatedLink = null;
0660: translatedLink = (String) m_fileIndex.get(link.replace('\\',
0661: '/'));
0662:
0663: if (translatedLink == null) {
0664: // its an anchor link, so copy use it
0665: if (link.startsWith("#")) {
0666: translatedLink = link;
0667: }
0668:
0669: // relative link to OpenCms root
0670: else if (link.startsWith("/")) {
0671:
0672: // strip cms context path
0673: if (link.startsWith(OpenCms.getSystemInfo()
0674: .getOpenCmsContext())) {
0675: link = link.substring(OpenCms.getSystemInfo()
0676: .getOpenCmsContext().length());
0677: }
0678:
0679: // check if resource exists
0680: if ((m_keepBrokenLinks)
0681: || (m_cmsObject.existsResource(link))) {
0682: translatedLink = link;
0683: }
0684: }
0685:
0686: else {
0687:
0688: String fileBase = getBasePath(m_inputDir, link);
0689: String cmsBase = (String) m_parents.get(fileBase);
0690: if (cmsBase != null) {
0691: String outLink = cmsBase
0692: + link.substring(fileBase.length())
0693: .replace('\\', '/');
0694: if ((m_keepBrokenLinks)
0695: || (m_cmsObject.existsResource(outLink))) {
0696: translatedLink = outLink;
0697: }
0698: }
0699: }
0700: }
0701:
0702: // if the link goes to a directory, lets link to the index page within
0703: if ((translatedLink != null) && translatedLink.endsWith("/")) {
0704: translatedLink += "index.html";
0705: }
0706:
0707: // final check: if the translated link is still null the original link found
0708: // was broken
0709: // lets link it to the same page, the link is found on
0710: if (translatedLink == null) {
0711: translatedLink = "#";
0712: }
0713:
0714: return translatedLink;
0715: }
0716:
0717: /**
0718: * Tests if all given input parameters for the HTML Import are valid, that is that all the
0719: * given folders do exist. <p>
0720: *
0721: * @param fi a file item if a file is uploaded per HTTP otherwise <code>null</code>
0722: * @param isdefault if this sets, then the destination and input directory can be empty
0723: *
0724: * @throws CmsIllegalArgumentException if some parameters are not valid
0725: */
0726: public void validate(FileItem fi, boolean isdefault)
0727: throws CmsIllegalArgumentException {
0728:
0729: // check the input directory and the HTTP upload file
0730: if (fi == null) {
0731:
0732: if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_inputDir)
0733: && !isdefault) {
0734: throw new CmsIllegalArgumentException(Messages.get()
0735: .container(Messages.GUI_HTMLIMPORT_INPUTDIR_1,
0736: m_inputDir));
0737: } else if (!CmsStringUtil
0738: .isEmptyOrWhitespaceOnly(m_inputDir)) {
0739:
0740: File inputDir = new File(m_inputDir);
0741: if (!inputDir.exists() || inputDir.isFile()) {
0742: throw new CmsIllegalArgumentException(Messages
0743: .get().container(
0744: Messages.GUI_HTMLIMPORT_INPUTDIR_1,
0745: m_inputDir));
0746: }
0747: }
0748: }
0749:
0750: // check the destination directory
0751: try {
0752: if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_destinationDir)
0753: && !isdefault) {
0754: throw new CmsIllegalArgumentException(Messages.get()
0755: .container(Messages.GUI_HTMLIMPORT_DESTDIR_1,
0756: m_destinationDir));
0757: } else if (!CmsStringUtil
0758: .isEmptyOrWhitespaceOnly(m_destinationDir)) {
0759: m_cmsObject.readFolder(m_destinationDir);
0760: }
0761:
0762: } catch (CmsException e) {
0763: // an exception is thrown if the folder does not exist
0764: throw new CmsIllegalArgumentException(Messages.get()
0765: .container(Messages.GUI_HTMLIMPORT_DESTDIR_1,
0766: m_destinationDir), e);
0767: }
0768:
0769: // check the image gallery
0770: // only if flag for leaving images at original location is off
0771: if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_imageGallery)) {
0772: try {
0773: CmsFolder folder = m_cmsObject
0774: .readFolder(m_imageGallery);
0775: // check if folder is a image gallery
0776: String name = OpenCms.getResourceManager()
0777: .getResourceType(folder.getTypeId())
0778: .getTypeName();
0779: if (!name.equals("imagegallery")) {
0780: throw new CmsIllegalArgumentException(
0781: Messages
0782: .get()
0783: .container(
0784: Messages.GUI_HTMLIMPORT_IMGGALLERY_INVALID_1,
0785: m_imageGallery));
0786: }
0787: } catch (CmsException e) {
0788: // an exception is thrown if the folder does not exist
0789: throw new CmsIllegalArgumentException(Messages.get()
0790: .container(
0791: Messages.GUI_HTMLIMPORT_IMGGALLERY_1,
0792: m_imageGallery), e);
0793: }
0794: }
0795:
0796: // check the link gallery
0797: // only if flag for leaving external links at original location is off
0798: if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_linkGallery)) {
0799: try {
0800: CmsFolder folder = m_cmsObject
0801: .readFolder(m_linkGallery);
0802: // check if folder is a link gallery
0803: String name = OpenCms.getResourceManager()
0804: .getResourceType(folder.getTypeId())
0805: .getTypeName();
0806: if (!name.equals("linkgallery")) {
0807: throw new CmsIllegalArgumentException(
0808: Messages
0809: .get()
0810: .container(
0811: Messages.GUI_HTMLIMPORT_LINKGALLERY_INVALID_1,
0812: m_linkGallery));
0813: }
0814: } catch (CmsException e) {
0815: // an exception is thrown if the folder does not exist
0816: throw new CmsIllegalArgumentException(Messages.get()
0817: .container(
0818: Messages.GUI_HTMLIMPORT_LINKGALLERY_1,
0819: m_linkGallery), e);
0820: }
0821: }
0822:
0823: // check the download gallery
0824: if ((!isExternal(m_downloadGallery))
0825: && (!CmsStringUtil
0826: .isEmptyOrWhitespaceOnly(m_downloadGallery))) {
0827: try {
0828: CmsFolder folder = m_cmsObject
0829: .readFolder(m_downloadGallery);
0830: // check if folder is a download gallery
0831: String name = OpenCms.getResourceManager()
0832: .getResourceType(folder.getTypeId())
0833: .getTypeName();
0834: if (!name.equals("downloadgallery")) {
0835: throw new CmsIllegalArgumentException(
0836: Messages
0837: .get()
0838: .container(
0839: Messages.GUI_HTMLIMPORT_DOWNGALLERY_INVALID_1,
0840: m_downloadGallery));
0841: }
0842: } catch (CmsException e) {
0843: // an exception is thrown if the folder does not exist
0844: throw new CmsIllegalArgumentException(Messages.get()
0845: .container(
0846: Messages.GUI_HTMLIMPORT_DOWNGALLERY_1,
0847: m_downloadGallery), e);
0848: }
0849: }
0850:
0851: // check the template
0852: try {
0853: m_cmsObject.readResource(m_template, CmsResourceFilter.ALL);
0854: } catch (CmsException e) {
0855: // an exception is thrown if the template does not exist
0856: if (!isValidElement()) {
0857: throw new CmsIllegalArgumentException(Messages.get()
0858: .container(Messages.GUI_HTMLIMPORT_TEMPLATE_1,
0859: m_template), e);
0860: }
0861: }
0862:
0863: // check the element
0864: if (!isValidElement()) {
0865: throw new CmsIllegalArgumentException(Messages.get()
0866: .container(Messages.GUI_HTMLIMPORT_INVALID_ELEM_2,
0867: m_element, m_template));
0868: }
0869:
0870: // check if we are in an offline project
0871: if (m_cmsObject.getRequestContext().currentProject()
0872: .isOnlineProject()) {
0873: throw new CmsIllegalArgumentException(
0874: Messages
0875: .get()
0876: .container(
0877: Messages.GUI_HTMLIMPORT_CONSTRAINT_OFFLINE_0));
0878: }
0879: }
0880:
0881: /**
0882: * Builds an index of all files to be imported and determines their new names in the OpenCms.<p>
0883: *
0884: * @param startfolder the folder to start with
0885: *
0886: * @throws Exception if something goes wrong
0887: */
0888: private void buildIndex(String startfolder) throws Exception {
0889:
0890: File folder = new File(startfolder);
0891: // get all subresources
0892:
0893: File[] subresources = folder.listFiles();
0894: // now loop through all subresources and add them to the index list
0895: for (int i = 0; i < subresources.length; i++) {
0896: try {
0897:
0898: String relativeFSName = subresources[i]
0899: .getAbsolutePath().substring(
0900: m_inputDir.length() + 1);
0901: String absoluteVFSName = getVfsName(relativeFSName,
0902: subresources[i].getName(), subresources[i]
0903: .isFile());
0904: m_report.print(Messages.get().container(
0905: Messages.RPT_CREATE_INDEX_0),
0906: I_CmsReport.FORMAT_NOTE);
0907: m_report
0908: .print(org.opencms.report.Messages
0909: .get()
0910: .container(
0911: org.opencms.report.Messages.RPT_ARGUMENT_1,
0912: relativeFSName.replace('\\',
0913: '/')));
0914: m_report
0915: .print(org.opencms.report.Messages
0916: .get()
0917: .container(
0918: org.opencms.report.Messages.RPT_DOTS_0));
0919: m_report.print(Messages.get().container(
0920: Messages.RPT_ARROW_RIGHT_0),
0921: I_CmsReport.FORMAT_NOTE);
0922: m_report
0923: .print(org.opencms.report.Messages
0924: .get()
0925: .container(
0926: org.opencms.report.Messages.RPT_ARGUMENT_1,
0927: absoluteVFSName));
0928: m_report
0929: .print(org.opencms.report.Messages
0930: .get()
0931: .container(
0932: org.opencms.report.Messages.RPT_DOTS_0));
0933: m_fileIndex.put(subresources[i].getAbsolutePath()
0934: .replace('\\', '/'), absoluteVFSName);
0935: // if the subresource is a folder, get all subresources of it as well
0936: if (subresources[i].isDirectory()) {
0937: buildIndex(subresources[i].getAbsolutePath());
0938: }
0939: m_report.println(
0940: org.opencms.report.Messages.get().container(
0941: org.opencms.report.Messages.RPT_OK_0),
0942: I_CmsReport.FORMAT_OK);
0943: } catch (Exception e) {
0944: LOG.error(e.getLocalizedMessage(), e);
0945: m_report.println(e);
0946: }
0947: }
0948: }
0949:
0950: /**
0951: * Builds a map with all parents of the destination directory to the real file system.<p>
0952: * So links to resources of outside the import folder can be found.<p>
0953: */
0954: private void buildParentPath() {
0955:
0956: String destFolder = m_destinationDir;
0957: String inputDir = m_inputDir.replace('\\', '/');
0958: if (!inputDir.endsWith("/")) {
0959: inputDir += "/";
0960: }
0961: int pos = inputDir.lastIndexOf("/");
0962: while ((pos > 0) && (destFolder != null)) {
0963: inputDir = inputDir.substring(0, pos);
0964: m_parents.put(inputDir + "/", destFolder);
0965:
0966: pos = inputDir.lastIndexOf("/", pos - 1);
0967: destFolder = CmsResource.getParentFolder(destFolder);
0968: }
0969: }
0970:
0971: /**
0972: * This function close a InputStream.<p>
0973: *
0974: * @param stream the <code> {@link InputStream} </code> Object
0975: */
0976: private void closeStream(InputStream stream) {
0977:
0978: if (stream != null) {
0979: try {
0980: stream.close();
0981: } catch (Exception ex) {
0982: LOG.error(ex.getLocalizedMessage(), ex);
0983: }
0984: }
0985: }
0986:
0987: /**
0988: * Copies all HTML files to the VFS.<p>
0989: *
0990: * @param startfolder the folder to start with
0991: *
0992: * @throws Exception if something goes wrong
0993: */
0994: private void copyHtmlFiles(String startfolder) throws Exception {
0995:
0996: try {
0997: File folder = new File(startfolder);
0998: // get all subresources
0999: File[] subresources = folder.listFiles();
1000: // now loop through all subresources
1001: for (int i = 0; i < subresources.length; i++) {
1002: // if the subresource is a folder, get all subresources of it as well
1003: if (subresources[i].isDirectory()) {
1004: // first, create the folder in the VFS
1005: Hashtable properties = new Hashtable();
1006: createFolder(subresources[i].getAbsolutePath(), i,
1007: properties);
1008: // now process all rescources inside of the folder
1009: copyHtmlFiles(subresources[i].getAbsolutePath());
1010: } else {
1011: // create a new file in the VFS
1012: String vfsFileName = (String) m_fileIndex
1013: .get(subresources[i].getAbsolutePath()
1014: .replace('\\', '/'));
1015: // check if this is an HTML file, do only import and parse those
1016: int type = getFileType(vfsFileName);
1017: if (CmsResourceTypePlain.getStaticTypeId() == type) {
1018: Hashtable properties = new Hashtable();
1019: // the subresource is a file, so start the parsing process
1020: String content = "";
1021: try {
1022: content = parseHtmlFile(subresources[i],
1023: properties);
1024: } catch (CmsException e) {
1025: m_report.println(e);
1026: }
1027: properties.put("template", m_template);
1028:
1029: // create the file in the VFS
1030: createFile(subresources[i].getAbsolutePath(),
1031: i, content, properties);
1032: }
1033: }
1034: }
1035: } catch (Exception e) {
1036: LOG.error(e.getLocalizedMessage(), e);
1037: }
1038: }
1039:
1040: /**
1041: * Copies all files except HTML files to the VFS.<p>
1042: *
1043: * @param startfolder the folder to start with
1044: */
1045: private void copyOtherFiles(String startfolder) {
1046:
1047: try {
1048: File folder = new File(startfolder);
1049: // get all subresources
1050: File[] subresources = folder.listFiles();
1051: // now loop through all subresources
1052: for (int i = 0; i < subresources.length; i++) {
1053: // if the subresource is a folder, get all subresources of it as well
1054: if (subresources[i].isDirectory()) {
1055: copyOtherFiles(subresources[i].getAbsolutePath());
1056: } else {
1057: // do not import the "meta.properties" file
1058: if (!subresources[i].getName().equals(
1059: META_PROPERTIES)) {
1060: // create a new file in the VFS
1061: String vfsFileName = (String) m_fileIndex
1062: .get(subresources[i].getAbsolutePath()
1063: .replace('\\', '/'));
1064: // get the file type of the FS file
1065: int type = getFileType(vfsFileName);
1066: if (CmsResourceTypePlain.getStaticTypeId() != type) {
1067:
1068: if (isExternal(vfsFileName)) {
1069:
1070: m_report
1071: .print(
1072: Messages
1073: .get()
1074: .container(
1075: Messages.RPT_SKIP_EXTERNAL_0),
1076: I_CmsReport.FORMAT_NOTE);
1077: m_report
1078: .print(org.opencms.report.Messages
1079: .get()
1080: .container(
1081: org.opencms.report.Messages.RPT_ARGUMENT_1,
1082: subresources[i]));
1083: m_report
1084: .print(org.opencms.report.Messages
1085: .get()
1086: .container(
1087: org.opencms.report.Messages.RPT_DOTS_0));
1088: m_report
1089: .print(
1090: Messages
1091: .get()
1092: .container(
1093: Messages.RPT_ARROW_RIGHT_0),
1094: I_CmsReport.FORMAT_NOTE);
1095: m_report
1096: .println(org.opencms.report.Messages
1097: .get()
1098: .container(
1099: org.opencms.report.Messages.RPT_ARGUMENT_1,
1100: vfsFileName));
1101: } else {
1102:
1103: m_report.print(Messages.get()
1104: .container(
1105: Messages.RPT_IMPORT_0),
1106: I_CmsReport.FORMAT_NOTE);
1107: m_report
1108: .print(org.opencms.report.Messages
1109: .get()
1110: .container(
1111: org.opencms.report.Messages.RPT_ARGUMENT_1,
1112: vfsFileName));
1113: m_report
1114: .print(org.opencms.report.Messages
1115: .get()
1116: .container(
1117: org.opencms.report.Messages.RPT_DOTS_0));
1118:
1119: // get the content of the FS file
1120: byte[] content = getFileBytes(subresources[i]);
1121: // get the filename from the fileIndex list
1122:
1123: // check if there are some image info's stored for this resource
1124: List properties = new ArrayList();
1125: String altText = (String) m_imageInfo
1126: .get(subresources[i]
1127: .getAbsolutePath()
1128: .replace('\\', '/'));
1129: CmsProperty property1 = new CmsProperty(
1130: CmsPropertyDefinition.PROPERTY_DESCRIPTION,
1131: altText, altText);
1132: CmsProperty property2 = new CmsProperty(
1133: CmsPropertyDefinition.PROPERTY_TITLE,
1134: altText, altText);
1135: // add them to the title and description property
1136: if (altText != null) {
1137: properties.add(property1);
1138: properties.add(property2);
1139: }
1140: // create the file
1141: if (!m_overwrite) {
1142: m_cmsObject.createResource(
1143: vfsFileName, type, content,
1144: properties);
1145: } else {
1146: try {
1147: CmsLock lock = m_cmsObject
1148: .getLock(vfsFileName);
1149: if (lock.getType() != CmsLockType.EXCLUSIVE) {
1150: m_cmsObject
1151: .lockResource(vfsFileName);
1152: }
1153: m_cmsObject
1154: .deleteResource(
1155: vfsFileName,
1156: CmsResource.DELETE_PRESERVE_SIBLINGS);
1157: } catch (CmsException e) {
1158: // the file did not exist, so create it
1159: } finally {
1160: m_cmsObject.createResource(
1161: vfsFileName, type,
1162: content, properties);
1163: }
1164:
1165: m_report
1166: .print(
1167: Messages
1168: .get()
1169: .container(
1170: Messages.RPT_OVERWRITE_0),
1171: I_CmsReport.FORMAT_NOTE);
1172: m_report
1173: .print(org.opencms.report.Messages
1174: .get()
1175: .container(
1176: org.opencms.report.Messages.RPT_DOTS_0));
1177: }
1178: m_report
1179: .println(
1180: org.opencms.report.Messages
1181: .get()
1182: .container(
1183: org.opencms.report.Messages.RPT_OK_0),
1184: I_CmsReport.FORMAT_OK);
1185: }
1186: }
1187: }
1188: }
1189: }
1190: } catch (Exception e) {
1191: LOG.error(e.getLocalizedMessage(), e);
1192: m_report.println(e);
1193: }
1194: }
1195:
1196: /**
1197: * Creates all external links, which were found during the HTML-page processing.<p>
1198: *
1199: */
1200: private void createExternalLinks() {
1201:
1202: // loop through all links
1203: Iterator i = m_externalLinks.iterator();
1204: while (i.hasNext()) {
1205: String linkUrl = (String) i.next();
1206: String filename = getExternalLinkFile(linkUrl);
1207:
1208: m_report.print(Messages.get().container(
1209: Messages.RPT_CREATE_EXTERNAL_LINK_0),
1210: I_CmsReport.FORMAT_NOTE);
1211: m_report.print(org.opencms.report.Messages.get().container(
1212: org.opencms.report.Messages.RPT_ARGUMENT_1,
1213: filename));
1214: m_report.print(org.opencms.report.Messages.get().container(
1215: org.opencms.report.Messages.RPT_DOTS_0));
1216:
1217: List properties = new ArrayList();
1218: CmsProperty property1 = new CmsProperty(
1219: CmsPropertyDefinition.PROPERTY_TITLE, "Link to "
1220: + linkUrl, "Link to " + linkUrl);
1221: properties.add(property1);
1222: try {
1223: m_cmsObject.createResource(m_linkGallery + filename,
1224: CmsResourceTypePointer.getStaticTypeId(),
1225: linkUrl.getBytes(), properties);
1226: } catch (CmsException e) {
1227: // do nothing here, an exception will be thrown if this link already exists
1228: }
1229: m_report.println(org.opencms.report.Messages.get()
1230: .container(org.opencms.report.Messages.RPT_OK_0),
1231: I_CmsReport.FORMAT_OK);
1232: }
1233: }
1234:
1235: /**
1236: * Creates a file in the VFS.<p>
1237: *
1238: * @param filename the complete filename in the real file system
1239: * @param position the default navigation position of this folder
1240: * @param content the HTML content of the file
1241: * @param properties the file properties
1242: */
1243: private void createFile(String filename, int position,
1244: String content, Hashtable properties) {
1245:
1246: String vfsFileName = (String) m_fileIndex.get(filename.replace(
1247: '\\', '/'));
1248:
1249: if (vfsFileName != null) {
1250: try {
1251:
1252: m_report.print(Messages.get().container(
1253: Messages.RPT_CREATE_FILE_0),
1254: I_CmsReport.FORMAT_NOTE);
1255: m_report
1256: .print(org.opencms.report.Messages
1257: .get()
1258: .container(
1259: org.opencms.report.Messages.RPT_ARGUMENT_1,
1260: vfsFileName));
1261: m_report
1262: .print(org.opencms.report.Messages
1263: .get()
1264: .container(
1265: org.opencms.report.Messages.RPT_DOTS_0));
1266:
1267: // check if we have to set the navpos property.
1268: if ((properties
1269: .get(CmsPropertyDefinition.PROPERTY_NAVPOS) == null)
1270: && (properties
1271: .get(CmsPropertyDefinition.PROPERTY_NAVTEXT) != null)) {
1272: // set the position in the folder as navpos
1273: // we have to add one to the position, since it is counted from 0
1274: properties.put(
1275: CmsPropertyDefinition.PROPERTY_NAVPOS,
1276: (position + 1) + "");
1277: }
1278:
1279: // create new XML page
1280: Locale locale = new Locale(m_locale);
1281: CmsXmlPage page = new CmsXmlPage(locale, OpenCms
1282: .getSystemInfo().getDefaultEncoding());
1283: page.addValue(m_element, locale);
1284: page.setStringValue(m_cmsObject, m_element, locale,
1285: content);
1286:
1287: // check links
1288: CmsLinkTable linkTable = page.getLinkTable(m_element,
1289: locale);
1290: Iterator i = linkTable.iterator();
1291: while (i.hasNext()) {
1292: CmsLink link = (CmsLink) i.next();
1293: String target = link.getTarget();
1294: // do only update internal links
1295: if (link.isInternal()) {
1296: target = m_cmsObject.getRequestContext()
1297: .getFileTranslator().translateResource(
1298: target);
1299: // update link
1300: link.updateLink(target, link.getAnchor(), link
1301: .getQuery());
1302: link.checkConsistency(m_cmsObject);
1303: }
1304: }
1305: // marshal XML page and get the content
1306: byte[] contentByteArray = page.marshal();
1307: List oldProperties = new ArrayList();
1308:
1309: if (!m_overwrite) {
1310: m_cmsObject.createResource(vfsFileName,
1311: CmsResourceTypeXmlPage.getStaticTypeId(),
1312: contentByteArray, new ArrayList());
1313: } else {
1314: try {
1315: // try if the file is there
1316: oldProperties = m_cmsObject
1317: .readPropertyObjects(vfsFileName, false);
1318: CmsLock lock = m_cmsObject.getLock(vfsFileName);
1319: if (lock.getType() != CmsLockType.EXCLUSIVE) {
1320: m_cmsObject.lockResource(vfsFileName);
1321: }
1322: m_cmsObject.deleteResource(vfsFileName,
1323: CmsResource.DELETE_PRESERVE_SIBLINGS);
1324: } catch (CmsException e) {
1325: // the file did not exist, so we do not have to delete it
1326: } finally {
1327: // create the new resource
1328: m_report.print(Messages.get().container(
1329: Messages.RPT_OVERWRITE_0),
1330: I_CmsReport.FORMAT_NOTE);
1331: m_report
1332: .print(org.opencms.report.Messages
1333: .get()
1334: .container(
1335: org.opencms.report.Messages.RPT_DOTS_0));
1336: m_cmsObject.createResource(vfsFileName,
1337: CmsResourceTypeXmlPage
1338: .getStaticTypeId(),
1339: contentByteArray, new ArrayList());
1340: }
1341: }
1342: // create all properties and put them in an ArrayList
1343: Iterator it = properties.entrySet().iterator();
1344: List propertyList = new ArrayList();
1345: while (it.hasNext()) {
1346: // get property and value
1347: Map.Entry entry = (Map.Entry) it.next();
1348: String propertyKey = (String) entry.getKey();
1349: String propertyVal = (String) entry.getValue();
1350: // create new Property Object
1351: CmsProperty property = new CmsProperty(propertyKey,
1352: propertyVal, propertyVal);
1353: // create implicitly if Property doesn't exist already
1354: property.setAutoCreatePropertyDefinition(true);
1355: // add new property to the list
1356: propertyList.add(property);
1357: }
1358: // try to write the properties
1359: try {
1360: m_cmsObject.writePropertyObjects(vfsFileName,
1361: propertyList);
1362: // write the old properties if available
1363: m_cmsObject.writePropertyObjects(vfsFileName,
1364: oldProperties);
1365: } catch (CmsException e1) {
1366: e1.printStackTrace();
1367: }
1368: m_report.println(
1369: org.opencms.report.Messages.get().container(
1370: org.opencms.report.Messages.RPT_OK_0),
1371: I_CmsReport.FORMAT_OK);
1372: } catch (CmsException e) {
1373: m_report.println(e);
1374: LOG.error(e.getLocalizedMessage(), e);
1375: }
1376: }
1377: }
1378:
1379: /**
1380: * Creates a folder in the VFS.<p>
1381: *
1382: * @param foldername the complete folder name in the real file system
1383: * @param position the default navigation position of this folder
1384: * @param properties the file properties
1385: */
1386: private void createFolder(String foldername, int position,
1387: Hashtable properties) {
1388:
1389: String vfsFolderName = (String) m_fileIndex.get(foldername
1390: .replace('\\', '/'));
1391:
1392: m_report.print(Messages.get().container(
1393: Messages.RPT_CREATE_FOLDER_0), I_CmsReport.FORMAT_NOTE);
1394: m_report.print(org.opencms.report.Messages.get().container(
1395: org.opencms.report.Messages.RPT_ARGUMENT_1,
1396: vfsFolderName));
1397: m_report.print(org.opencms.report.Messages.get().container(
1398: org.opencms.report.Messages.RPT_DOTS_0));
1399:
1400: if (vfsFolderName != null) {
1401: String path = vfsFolderName.substring(0, vfsFolderName
1402: .substring(0, vfsFolderName.length() - 1)
1403: .lastIndexOf("/"));
1404: String folder = vfsFolderName.substring(path.length(),
1405: vfsFolderName.length());
1406: try {
1407: // try to find a meta.properties file in the folder
1408: String propertyFileName = foldername + File.separator
1409: + META_PROPERTIES;
1410:
1411: boolean metaPropertiesFound = false;
1412: ExtendedProperties propertyFile = new ExtendedProperties();
1413: try {
1414: propertyFile.load(new FileInputStream(new File(
1415: propertyFileName)));
1416: metaPropertiesFound = true;
1417: } catch (Exception e1) {
1418: // do nothing if the property file could not be loaded since it is not required
1419: // that such s file does exist
1420: }
1421: // now copy all values from the property file to the already found properties of the
1422: // new folder in OpenCms
1423: // only do this if we have found a meta.properties file
1424: if (metaPropertiesFound) {
1425: Enumeration enu = propertyFile.keys();
1426: String property = "";
1427: while (enu.hasMoreElements()) {
1428: // get property and value
1429: try {
1430: property = (String) enu.nextElement();
1431: String propertyvalue = (String) propertyFile
1432: .get(property);
1433: // copy to the properties of the OpenCms folder
1434: properties.put(property, propertyvalue);
1435: } catch (Exception e2) {
1436: // just skip this property if it could not be read.
1437: e2.printStackTrace();
1438: }
1439: }
1440:
1441: // check if we have to set the navpos property.
1442: if (properties
1443: .get(CmsPropertyDefinition.PROPERTY_NAVPOS) == null) {
1444: // set the position in the folder as navpos
1445: // we have to add one to the position, since it is counted from 0
1446: properties.put(
1447: CmsPropertyDefinition.PROPERTY_NAVPOS,
1448: (position + 1) + "");
1449: }
1450: // check if we have to set the navpos property.
1451: if (properties
1452: .get(CmsPropertyDefinition.PROPERTY_NAVTEXT) == null) {
1453: // set the foldername in the folder as navtext
1454: String navtext = folder.substring(1, 2)
1455: .toUpperCase()
1456: + folder.substring(2,
1457: folder.length() - 1);
1458: properties.put(
1459: CmsPropertyDefinition.PROPERTY_NAVTEXT,
1460: navtext);
1461: }
1462: } else {
1463: // if there was no meta.properties file, no properties should be added to the
1464: // folder
1465: properties = new Hashtable();
1466: }
1467: // try to read the folder, it its there we must not create it again
1468: try {
1469: m_cmsObject.readFolder(path + folder);
1470: m_cmsObject.lockResource(path + folder);
1471: } catch (CmsException e1) {
1472: // the folder was not there, so create it
1473: m_cmsObject.createResource(path + folder,
1474: CmsResourceTypeFolder.getStaticTypeId());
1475: }
1476: // create all properties and put them in an ArrayList
1477: Enumeration enu = properties.keys();
1478: List propertyList = new ArrayList();
1479: while (enu.hasMoreElements()) {
1480: // get property and value
1481: String propertyKey = (String) enu.nextElement();
1482: String propertyVal = (String) properties
1483: .get(propertyKey);
1484: CmsProperty property = new CmsProperty(propertyKey,
1485: propertyVal, propertyVal);
1486: // create implicitly if Property doesn't exist already
1487: property.setAutoCreatePropertyDefinition(true);
1488: // add new property to the list
1489: propertyList.add(property);
1490: }
1491: // try to write the property Objects
1492: try {
1493: m_cmsObject.writePropertyObjects(path + folder,
1494: propertyList);
1495: } catch (CmsException e1) {
1496: e1.printStackTrace();
1497: }
1498: m_report.println(
1499: org.opencms.report.Messages.get().container(
1500: org.opencms.report.Messages.RPT_OK_0),
1501: I_CmsReport.FORMAT_OK);
1502: } catch (CmsException e) {
1503: m_report.println(e);
1504: LOG.error(e.getLocalizedMessage(), e);
1505: }
1506: }
1507: }
1508:
1509: /**
1510: * Compares two path's for the base part which have both equal.<p>
1511: *
1512: * @param path1 the first path to compare
1513: * @param path2 the second path to compare
1514: *
1515: * @return the base path of both which are equal
1516: */
1517: private String getBasePath(String path1, String path2) {
1518:
1519: StringBuffer base = new StringBuffer();
1520: path1 = path1.replace('\\', '/');
1521: path2 = path2.replace('\\', '/');
1522:
1523: String[] parts1 = path1.split("/");
1524: String[] parts2 = path2.split("/");
1525:
1526: for (int i = 0; i < parts1.length; i++) {
1527: if (i >= parts2.length) {
1528: break;
1529: }
1530: if (parts1[i].equals(parts2[i])) {
1531: base.append(parts1[i] + "/");
1532: }
1533: }
1534:
1535: return base.toString();
1536: }
1537:
1538: /**
1539: * Creates the filename of the file of the external link.<p>
1540: *
1541: * @param link the link to get the file path for.
1542: *
1543: * @return the filename of the file for the external link.
1544: */
1545: private String getExternalLinkFile(String link) {
1546:
1547: String filename = link.substring(link.indexOf("://") + 3, link
1548: .length());
1549: filename = m_cmsObject.getRequestContext().getFileTranslator()
1550: .translateResource(filename.replace('/', '-'));
1551: return filename;
1552: }
1553:
1554: /**
1555: * Returns a byte array containing the content of server FS file.<p>
1556: *
1557: * @param file the name of the file to read
1558: *
1559: * @return bytes[] the content of the file
1560: *
1561: * @throws CmsException if something goes wrong
1562: */
1563: private byte[] getFileBytes(File file) throws CmsException {
1564:
1565: byte[] buffer = null;
1566:
1567: FileInputStream fileStream = null;
1568: int charsRead;
1569: int size;
1570: try {
1571: fileStream = new FileInputStream(file);
1572: charsRead = 0;
1573: size = new Long(file.length()).intValue();
1574: buffer = new byte[size];
1575: while (charsRead < size) {
1576: charsRead += fileStream.read(buffer, charsRead, size
1577: - charsRead);
1578: }
1579: return buffer;
1580: } catch (IOException e) {
1581: throw new CmsDbIoException(Messages.get().container(
1582: Messages.ERR_GET_FILE_BYTES_1,
1583: file.getAbsolutePath()), e);
1584: } finally {
1585: closeStream(fileStream);
1586: }
1587: }
1588:
1589: /**
1590: * Returns the OpenCms file type of a real file system file. <p>
1591: * This is made by checking the extension.<p>
1592: *
1593: * @param filename the name of the file in the real file system
1594: *
1595: * @return the id of the OpenCms file type
1596: *
1597: * @throws Exception if something goes wrong
1598: */
1599: private int getFileType(String filename) throws Exception {
1600:
1601: String extension = "";
1602: if (filename.indexOf(".") > -1) {
1603: extension = filename.substring((filename.lastIndexOf(".")));
1604: }
1605:
1606: String typename = (String) m_extensions.get(extension
1607: .toLowerCase());
1608: if (typename == null) {
1609: typename = "binary";
1610: }
1611: CmsResourceManager resourceManager = OpenCms
1612: .getResourceManager();
1613:
1614: return resourceManager.getResourceType(typename).getTypeId();
1615: }
1616:
1617: /**
1618: * Gets a valid VfsName form a given name in the real file system.<p>
1619: *
1620: * This name will later be used for all link translations during the HTML-parsing process.<p>
1621: *
1622: * @param relativeName the name in the real file system, relative to the start folder
1623: * @param name the name of the file
1624: * @param isFile flag to indicate that the resource is a file
1625: *
1626: * @return a valid name in the VFS
1627: *
1628: * @throws Exception if something goes wrong
1629: */
1630: private String getVfsName(String relativeName, String name,
1631: boolean isFile) throws Exception {
1632:
1633: // first translate all file-separators to the valid "/" in OpenCms
1634: String vfsName = relativeName.replace('\\', '/');
1635: // the resource is a file
1636: if (isFile) {
1637: // we must check if it might be copied into a gallery. this can be done by checking the
1638: // file extension
1639: int filetype = getFileType(name);
1640:
1641: // there is no name before the ".extension"
1642: if (name.indexOf(".") == 0) {
1643: name = "unknown" + name;
1644: int dot = relativeName.lastIndexOf(".");
1645:
1646: relativeName = relativeName.substring(0, dot) + name;
1647: }
1648:
1649: // depending on the file-type, the resource must be moved into a special folder in
1650: // OpenCms:
1651: // images -> move into image gallery, if flag to leave at original location is off
1652: // binary -> move into download gallery, if flag to leave at original location is off
1653: // plain -> move into destination folder
1654: // other -> move into download gallery, if flag to leave at original location is off
1655: boolean leaveImages = CmsStringUtil
1656: .isEmptyOrWhitespaceOnly(m_imageGallery);
1657: boolean leaveDownload = CmsStringUtil
1658: .isEmptyOrWhitespaceOnly(m_downloadGallery);
1659: if ((CmsResourceTypeImage.getStaticTypeId() == filetype)
1660: && (!leaveImages)) {
1661: // move to image gallery
1662: // as the image gallery is "flat", we must use the file name and not the complete
1663: // relative name
1664: vfsName = m_imageGallery + name;
1665: } else if ((CmsResourceTypePlain.getStaticTypeId() == filetype)
1666: || (leaveImages) || (leaveDownload)) {
1667: // move to destination folder
1668: //vfsName=m_destinationDir+relativeName;
1669:
1670: // we have to check if there is a folder with the same name but without extension
1671: // if so, we will move the file into the folder and name it "index.html"
1672: String folderName = relativeName;
1673: if (folderName.indexOf(".") > 0) {
1674: folderName = folderName.substring(0, folderName
1675: .indexOf("."));
1676: }
1677: folderName = m_inputDir + "\\" + folderName;
1678: File folder = new File(folderName);
1679:
1680: if (folder.isDirectory()) {
1681: vfsName = m_destinationDir
1682: + relativeName.substring(0, relativeName
1683: .indexOf(".")) + "/index.html";
1684: // System.err.println("MOVING "+ relativeName + " -> " + name.substring(0,name.indexOf("."))+"/index.html");
1685: } else {
1686: // move to destination folder
1687: vfsName = m_destinationDir + relativeName;
1688: }
1689:
1690: } else {
1691: // everything else will be moved to the download gallery.
1692: // as the download gallery is "flat", we must use the file name and not the complete
1693: // relative name
1694: vfsName = m_downloadGallery + name;
1695: }
1696: // now we have the filename in the VFS. its possible that a file with the same name
1697: // is already existing, in this case, we have to adjust the filename.
1698: return validateFilename(vfsName);
1699: } else {
1700: // folders are always moved to the destination folder
1701: vfsName = m_destinationDir + vfsName + "/";
1702: return vfsName;
1703: }
1704: }
1705:
1706: /**
1707: * Tests if a filename is an external name, that is this name does not point into the OpenCms VFS.<p>
1708: * A filename is an external name if it contains the string "://", e.g. "http://" or "ftp://".<p>
1709: *
1710: * @param filename the filename to test
1711: *
1712: * @return true or false
1713: */
1714: private boolean isExternal(String filename) {
1715:
1716: boolean external = false;
1717: if (filename.indexOf("://") > 0) {
1718: external = true;
1719: }
1720: return external;
1721: }
1722:
1723: /**
1724: * Checks if m_element is valid element.<p>
1725: *
1726: * @return true if element is valid, otherwise false
1727: */
1728: private boolean isValidElement() {
1729:
1730: boolean validElement = false;
1731: List elementList = new ArrayList();
1732: try {
1733: // get Elements of template stored in Property "template-elements"
1734: String elements = m_cmsObject.readPropertyObject(
1735: m_template,
1736: CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS,
1737: false).getValue();
1738: // template may contain more than one Element
1739: // Elements are separated by the delimiter ","
1740: if (elements != null) {
1741: StringTokenizer T = new StringTokenizer(elements, ",");
1742: while (T.hasMoreTokens()) {
1743: // current element probably looks like "body*|Body" <name><mandatory>|<nicename>
1744: String currentElement = T.nextToken();
1745: int sepIndex = currentElement.indexOf("|");
1746: if (sepIndex != -1) {
1747: // current element == "body*"
1748: currentElement = currentElement.substring(0,
1749: sepIndex);
1750: }
1751: if (currentElement.endsWith("*")) {
1752: // current element == "body"
1753: currentElement = currentElement.substring(0,
1754: currentElement.length() - 1);
1755: }
1756: elementList.add(currentElement);
1757: }
1758: }
1759: if (elementList.contains(m_element)) {
1760: validElement = true;
1761: }
1762: } catch (Exception e) {
1763: e.printStackTrace();
1764: }
1765:
1766: return validElement;
1767: }
1768:
1769: /**
1770: * Reads the content of an HTML file from the real file system and parses it for link
1771: * transformation.<p>
1772: *
1773: * @param file the file in the real file system
1774: * @param properties the file properties
1775: *
1776: * @return the modified HTML code of the file
1777: *
1778: * @throws CmsException if something goes wrong
1779: */
1780: private String parseHtmlFile(File file, Hashtable properties)
1781: throws CmsException {
1782:
1783: String parsedHtml = "";
1784: try {
1785:
1786: byte[] content = getFileBytes(file);
1787:
1788: // use the correct encoding to get the string from the file bytes
1789: String contentString = new String(content, m_inputEncoding);
1790: // escape the string to remove all special chars
1791: contentString = CmsEncoder.escapeNonAscii(contentString);
1792: // we must substitute all occurrences of "&#", otherwise tidy would remove them
1793: contentString = CmsStringUtil.substitute(contentString,
1794: "&#", "{subst}");
1795: // parse the content
1796: parsedHtml = m_htmlConverter.convertHTML(file
1797: .getAbsolutePath(), contentString, m_startPattern,
1798: m_endPattern, properties);
1799: // resubstitute the converted HTML code
1800: parsedHtml = CmsStringUtil.substitute(parsedHtml,
1801: "{subst}", "&#");
1802: } catch (Exception e) {
1803: CmsMessageContainer message = Messages.get().container(
1804: Messages.ERR_HTMLIMPORT_PARSE_1,
1805: file.getAbsolutePath());
1806: LOG.error(e.getLocalizedMessage(), e);
1807: throw new CmsImportExportException(message, e);
1808: }
1809: return parsedHtml;
1810: }
1811:
1812: /**
1813: * This function reads the zip-file and saved the files and directories in a new
1814: * temporary-folder.<p>
1815: *
1816: * @return the temporary-folder where the files from the zip-file are saved
1817: */
1818: private File unzipStream() {
1819:
1820: ZipInputStream importZip = null;
1821: File folder = null;
1822: try {
1823: // read the zip file
1824: importZip = new ZipInputStream(new FileInputStream(
1825: m_httpDir));
1826: // create a temporary-folder, where to unzip the zip file
1827: folder = createTempFolder("import_html");
1828: ZipEntry entry = null;
1829: byte[] buffer = null;
1830: while (true) {
1831: try {
1832: // get the next entry
1833: entry = importZip.getNextEntry();
1834: if (entry == null) {
1835: break;
1836: }
1837: String name = entry.getName();
1838: // make a report for the user
1839: m_report.print(Messages.get().container(
1840: Messages.RPT_HTML_UNZIP_0),
1841: I_CmsReport.FORMAT_NOTE);
1842: m_report
1843: .print(org.opencms.report.Messages
1844: .get()
1845: .container(
1846: org.opencms.report.Messages.RPT_ARGUMENT_1,
1847: name));
1848: m_report
1849: .print(org.opencms.report.Messages
1850: .get()
1851: .container(
1852: org.opencms.report.Messages.RPT_DOTS_0));
1853: // replace the VFS separator with the separator of the file system
1854: name = name.replace('/', File.separatorChar);
1855: String path = folder + File.separator + name;
1856: if (entry.isDirectory()) {
1857: // create a directory
1858: File importFile = new File(path);
1859: importFile.mkdirs();
1860: } else {
1861: // create a file and read the content
1862: int size = new Long(entry.getSize()).intValue();
1863: if (size == -1) {
1864: buffer = CmsFileUtil.readFully(importZip,
1865: false);
1866: } else {
1867: buffer = CmsFileUtil.readFully(importZip,
1868: size, false);
1869: }
1870: // create a new temporary file
1871: File importFile = new File(path);
1872: File parent = importFile.getParentFile();
1873: if (parent != null) {
1874: parent.mkdirs();
1875: }
1876: importFile.createNewFile();
1877: // write the content in the file
1878: FileOutputStream fileOutput = new FileOutputStream(
1879: importFile.getAbsoluteFile());
1880: fileOutput.write(buffer);
1881: fileOutput.close();
1882: }
1883: importZip.closeEntry();
1884: m_report
1885: .println(
1886: org.opencms.report.Messages
1887: .get()
1888: .container(
1889: org.opencms.report.Messages.RPT_OK_0),
1890: I_CmsReport.FORMAT_OK);
1891: } catch (Exception ex) {
1892: String name = (entry != null ? entry.getName() : "");
1893: if (LOG.isErrorEnabled()) {
1894: LOG
1895: .error(Messages.get().getBundle().key(
1896: Messages.ERR_ZIPFILE_UNZIP_1,
1897: name), ex);
1898: }
1899: m_report.println(Messages.get().container(
1900: Messages.ERR_ZIPFILE_UNZIP_1, name),
1901: I_CmsReport.FORMAT_ERROR);
1902: }
1903: entry = null;
1904: }
1905: } catch (Exception ex) {
1906: if (LOG.isErrorEnabled()) {
1907: LOG.error(Messages.get().getBundle().key(
1908: Messages.ERR_ZIPFILE_READ_1, m_httpDir), ex);
1909: }
1910: m_report.println(Messages.get().container(
1911: Messages.ERR_ZIPFILE_READ_1, m_httpDir),
1912: I_CmsReport.FORMAT_ERROR);
1913: } finally {
1914: closeStream(importZip);
1915: }
1916: return folder;
1917:
1918: }
1919:
1920: /**
1921: * Validates a filename for OpenCms.<p>
1922: *
1923: * This method checks if there are any illegal characters in the filename and modifies them
1924: * if necessary. In addition it ensures that no duplicate filenames are created.<p>
1925: *
1926: * @param filename the filename to validate
1927: *
1928: * @return a validated and unique filename in OpenCms
1929: */
1930: private String validateFilename(String filename) {
1931:
1932: // if its an external filename, use it directly
1933: if (isExternal(filename)) {
1934: return filename;
1935: }
1936:
1937: // check if this resource name does already exist
1938: // if so add a postfix to the name
1939:
1940: int postfix = 1;
1941: boolean found = true;
1942: String validFilename = filename;
1943:
1944: // if we are not in overwrite mode, we must find a valid, non-existing filename
1945: // otherwise we will use the current translated name
1946: if (!m_overwrite) {
1947:
1948: while (found) {
1949: try {
1950: // get the translated name, this one only contains valid chars in OpenCms
1951: validFilename = m_cmsObject.getRequestContext()
1952: .getFileTranslator().translateResource(
1953: validFilename);
1954:
1955: // try to read the file.....
1956: found = true;
1957: // first try to read it form the fileIndex of already processed files
1958: if (!m_fileIndex.containsValue(validFilename
1959: .replace('\\', '/'))) {
1960: found = false;
1961: }
1962: if (!found) {
1963: found = true;
1964: // there was no entry in the fileIndex, so try to read from the VFS
1965: m_cmsObject.readResource(validFilename,
1966: CmsResourceFilter.ALL);
1967: }
1968: // ....it's there, so add a postfix and try again
1969: String path = filename.substring(0, filename
1970: .lastIndexOf("/") + 1);
1971: String name = filename.substring(filename
1972: .lastIndexOf("/") + 1, filename.length());
1973: validFilename = path;
1974: if (name.lastIndexOf(".") > 0) {
1975: validFilename += name.substring(0, name
1976: .lastIndexOf("."));
1977: } else {
1978: validFilename += name;
1979: }
1980: validFilename += "_" + postfix;
1981: if (name.lastIndexOf(".") > 0) {
1982: validFilename += name.substring(name
1983: .lastIndexOf("."), name.length());
1984: }
1985: postfix++;
1986: } catch (CmsException e) {
1987: // the file does not exist, so we can use this filename
1988: found = false;
1989: }
1990: }
1991:
1992: } else {
1993: validFilename = validFilename.replace('\\', '/');
1994: }
1995:
1996: return OpenCms.getResourceManager().getFileTranslator()
1997: .translateResource(validFilename);
1998: }
1999:
2000: }
|