0001: /*
0002: * File : $Source: /usr/local/cvs/opencms/src/org/opencms/importexport/A_CmsImport.java,v $
0003: * Date : $Date: 2008-02-27 12:05:48 $
0004: * Version: $Revision: 1.89 $
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.importexport;
0033:
0034: import org.opencms.db.CmsUserSettings;
0035: import org.opencms.file.CmsGroup;
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.types.CmsResourceTypePointer;
0041: import org.opencms.i18n.CmsMessageContainer;
0042: import org.opencms.i18n.I_CmsMessageBundle;
0043: import org.opencms.main.CmsException;
0044: import org.opencms.main.CmsLog;
0045: import org.opencms.main.OpenCms;
0046: import org.opencms.report.I_CmsReport;
0047: import org.opencms.security.CmsAccessControlEntry;
0048: import org.opencms.security.CmsRole;
0049: import org.opencms.util.CmsFileUtil;
0050: import org.opencms.util.CmsStringUtil;
0051: import org.opencms.util.CmsUUID;
0052: import org.opencms.xml.CmsXmlUtils;
0053:
0054: import java.io.ByteArrayInputStream;
0055: import java.io.File;
0056: import java.io.FileNotFoundException;
0057: import java.io.IOException;
0058: import java.io.InputStream;
0059: import java.io.ObjectInputStream;
0060: import java.util.ArrayList;
0061: import java.util.HashMap;
0062: import java.util.Iterator;
0063: import java.util.List;
0064: import java.util.Locale;
0065: import java.util.Map;
0066: import java.util.Stack;
0067: import java.util.zip.ZipEntry;
0068: import java.util.zip.ZipException;
0069: import java.util.zip.ZipFile;
0070:
0071: import org.apache.commons.codec.binary.Base64;
0072: import org.apache.commons.logging.Log;
0073:
0074: import org.dom4j.Attribute;
0075: import org.dom4j.Document;
0076: import org.dom4j.Element;
0077:
0078: /**
0079: * Collection of common used methods for implementing OpenCms Import classes.<p>
0080: *
0081: * This class does not implement a real OpenCms import, real import implementation should be
0082: * inherited form this class.<p>
0083: *
0084: * @author Michael Emmerich
0085: * @author Thomas Weckert
0086: *
0087: * @version $Revision: 1.89 $
0088: *
0089: * @since 6.0.0
0090: *
0091: * @see org.opencms.importexport.I_CmsImport
0092: *
0093: * @deprecated the import is done starting with {@link CmsImportVersion7} with the digester
0094: */
0095: public abstract class A_CmsImport implements I_CmsImport {
0096:
0097: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "userinfo/entry@name" attribute, contains the additional user info entry name. */
0098: public static final String A_NAME = "name";
0099:
0100: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "userinfo/entry@type" attribute, contains the additional user info entry data type name. */
0101: public static final String A_TYPE = "type";
0102:
0103: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "access" node. */
0104: public static final String N_ACCESS = "access";
0105:
0106: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "allowed" node, to identify allowed user permissions. */
0107: public static final String N_ACCESSCONTROL_ALLOWEDPERMISSIONS = "allowed";
0108:
0109: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "denied" node, to identify denied user permissions. */
0110: public static final String N_ACCESSCONTROL_DENIEDPERMISSIONS = "denied";
0111:
0112: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "accesscontrol" node, to identify access control entries. */
0113: public static final String N_ACCESSCONTROL_ENTRIES = "accesscontrol";
0114:
0115: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "accessentry" node, to identify a single access control entry. */
0116: public static final String N_ACCESSCONTROL_ENTRY = "accessentry";
0117:
0118: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "permissionset" node, to identify a permission set. */
0119: public static final String N_ACCESSCONTROL_PERMISSIONSET = "permissionset";
0120:
0121: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "uuidprincipal" node, to identify a principal UUID. */
0122: public static final String N_ACCESSCONTROL_PRINCIPAL = "uuidprincipal";
0123:
0124: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "datecreated" node, contains the date created VFS file attribute. */
0125: public static final String N_DATECREATED = "datecreated";
0126:
0127: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "dateexpired" node, contains the expiration date VFS file attribute. */
0128: public static final String N_DATEEXPIRED = "dateexpired";
0129:
0130: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "datelastmodified" node, contains the date last modified VFS file attribute. */
0131: public static final String N_DATELASTMODIFIED = "datelastmodified";
0132:
0133: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "datereleased" node, contains the release date VFS file attribute. */
0134: public static final String N_DATERELEASED = "datereleased";
0135:
0136: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "defaultgroup" node, for backward compatibility with OpenCms 5.x. */
0137: public static final String N_DEFAULTGROUP = "defaultgroup";
0138:
0139: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "description" node, contains a users description test. */
0140: public static final String N_DESCRIPTION = "description";
0141:
0142: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "destination" node, contains target VFS file name. */
0143: public static final String N_DESTINATION = "destination";
0144:
0145: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "email" node, contains a users email. */
0146: public static final String N_EMAIL = "email";
0147:
0148: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "file" node, container node for all VFS resources. */
0149: public static final String N_FILE = "file";
0150:
0151: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "firstname" node, contains a users first name. */
0152: public static final String N_FIRSTNAME = "firstname";
0153:
0154: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "flags" node, contains the flags of a VFS resource. */
0155: public static final String N_FLAGS = "flags";
0156:
0157: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "groupdata" node, contains a users group data. */
0158: public static final String N_GROUPDATA = "groupdata";
0159:
0160: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "groupname" node, contains a groups name. */
0161: public static final String N_GROUPNAME = "groupname";
0162:
0163: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "id" node, only required for backward compatibility with import version 2. */
0164: public static final String N_ID = "id";
0165:
0166: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "lastmodified" node, only required for backward compatibility with import version 2. */
0167: public static final String N_LASTMODIFIED = "lastmodified";
0168:
0169: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "lastname" node, contains a users last name. */
0170: public static final String N_LASTNAME = "lastname";
0171:
0172: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "name" node, contains a users login name. */
0173: public static final String N_NAME = "name";
0174:
0175: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "orgunitdatas" node, starts the organizational unit data. */
0176: public static final String N_ORGUNITDATA = "orgunitdata";
0177:
0178: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "parentgroup" node, contains a groups parent group name. */
0179: public static final String N_PARENTGROUP = "parentgroup";
0180:
0181: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "password" node, contains a users encrypted password. */
0182: public static final String N_PASSWORD = "password";
0183:
0184: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "properties" node, starts the list of properties of a VFS resource. */
0185: public static final String N_PROPERTIES = "properties";
0186:
0187: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "property" node, starts a property for a VFS resource. */
0188: public static final String N_PROPERTY = "property";
0189:
0190: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "type" property attribute, contains a property type. */
0191: public static final String N_PROPERTY_ATTRIB_TYPE = "type";
0192:
0193: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "shared" property type attribute value. */
0194: public static final String N_PROPERTY_ATTRIB_TYPE_SHARED = "shared";
0195:
0196: /** Tag in the [@link #EXPORT_MANIFEST} for the "relation" node, starts a relation for a VFS resource. */
0197: public static final String N_RELATION = "relation";
0198:
0199: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "id" relation attribute, contains the structure id of the target resource of the relation. */
0200: public static final String N_RELATION_ATTRIBUTE_ID = "id";
0201:
0202: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "path" relation attribute, contains the path to the target resource of the relation. */
0203: public static final String N_RELATION_ATTRIBUTE_PATH = "path";
0204:
0205: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "type" relation attribute, contains the type of relation. */
0206: public static final String N_RELATION_ATTRIBUTE_TYPE = "type";
0207:
0208: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "relations" node, starts the list of relations of a VFS resources. */
0209: public static final String N_RELATIONS = "relations";
0210:
0211: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "source" node, contains the source path of a VFS resource in the import zip (or folder). */
0212: public static final String N_SOURCE = "source";
0213:
0214: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "address" node, contains a users address. */
0215: public static final String N_TAG_ADDRESS = "address";
0216:
0217: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "type" node, the resource type name of a VFS resource. */
0218: public static final String N_TYPE = "type";
0219:
0220: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "user" node, starts the user data. */
0221: public static final String N_USER = "user";
0222:
0223: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "usercreated" node, contains the name of the user who created the VFS resource. */
0224: public static final String N_USERCREATED = "usercreated";
0225:
0226: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "userdata" node, starts the list of users. */
0227: public static final String N_USERDATA = "userdata";
0228:
0229: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "usergroupdatas" node, starts the users group data. */
0230: public static final String N_USERGROUPDATA = "usergroupdata";
0231:
0232: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "usergroups" node, starts the users group data. */
0233: public static final String N_USERGROUPS = "usergroups";
0234:
0235: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "userinfo" node, contains the additional user info. */
0236: public static final String N_USERINFO = "userinfo";
0237:
0238: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "userinfo/entry" node, contains the additional user info entry value. */
0239: public static final String N_USERINFO_ENTRY = "entry";
0240:
0241: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "userlastmodified" node, contains the name of the user who last modified the VFS resource. */
0242: public static final String N_USERLASTMODIFIED = "userlastmodified";
0243:
0244: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "uuidresource" node, contains a the resource UUID of a VFS resource. */
0245: public static final String N_UUIDRESOURCE = "uuidresource";
0246:
0247: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "uuidstructure" node, only required for backward compatibility with import version 2. */
0248: public static final String N_UUIDSTRUCTURE = "uuidstructure";
0249:
0250: /** Tag in the {@link CmsImportExportManager#EXPORT_MANIFEST} for the "value" node, contains the value of a property. */
0251: public static final String N_VALUE = "value";
0252:
0253: /** The name of the legacy resource type "page". */
0254: public static final String RESOURCE_TYPE_LEGACY_PAGE_NAME = "page";
0255:
0256: /** Debug flag to show debug output. */
0257: protected static final int DEBUG = 0;
0258:
0259: /** The id of the legacy resource type "link". */
0260: protected static final int RESOURCE_TYPE_LINK_ID = 1024;
0261:
0262: /** The name of the legacy resource type "link". */
0263: protected static final String RESOURCE_TYPE_LINK_NAME = "link";
0264:
0265: /** The id of the legacy resource type "newpage". */
0266: protected static final int RESOURCE_TYPE_NEWPAGE_ID = 9;
0267:
0268: /** The name of the legacy resource type "newpage". */
0269: protected static final String RESOURCE_TYPE_NEWPAGE_NAME = "newpage";
0270:
0271: /** The log object for this class. */
0272: private static final Log LOG = CmsLog.getLog(A_CmsImport.class);
0273:
0274: /** The cms context to do the import operations with. */
0275: protected CmsObject m_cms;
0276:
0277: /** Flag for conversion to xml pages. */
0278: protected boolean m_convertToXmlPage;
0279:
0280: /** The xml manifest-file. */
0281: protected Document m_docXml;
0282:
0283: /** Groups to create during import are stored here. */
0284: protected Stack m_groupsToCreate;
0285:
0286: /** The import-path to write resources into the cms. */
0287: protected String m_importPath;
0288:
0289: /** The import-resource (folder) to load resources from. */
0290: protected File m_importResource;
0291:
0292: /** The import-resource (zip) to load resources from. */
0293: protected ZipFile m_importZip;
0294:
0295: /** Storage for all pointer properties which must be converted into links. */
0296: protected Map m_linkPropertyStorage;
0297:
0298: /** Storage for all pointers which must be converted into links. */
0299: protected Map m_linkStorage;
0300:
0301: /** The object to report the log messages. */
0302: protected I_CmsReport m_report;
0303:
0304: /** Messages object with the locale of the current user. */
0305: protected I_CmsMessageBundle m_userMessages;
0306:
0307: /**
0308: * Converts a given digest to base64 encoding.<p>
0309: *
0310: * @param value the digest value in the legacy encoding
0311: * @return the digest in the new encoding
0312: */
0313: public String convertDigestEncoding(String value) {
0314:
0315: byte[] data = new byte[value.length() / 2];
0316:
0317: for (int i = 0; i < data.length; i++) {
0318: data[i] = (byte) (Integer.parseInt(value.substring(i * 2,
0319: i * 2 + 2), 16) - 128);
0320: }
0321:
0322: return new String(Base64.encodeBase64(data));
0323: }
0324:
0325: /**
0326: * Returns the value of a child element with a specified name for a given parent element.<p>
0327: *
0328: * @param parentElement the parent element
0329: * @param elementName the child element name
0330: *
0331: * @return the value of the child node, or null if something went wrong
0332: */
0333: public String getChildElementTextValue(Element parentElement,
0334: String elementName) {
0335:
0336: try {
0337: // get the first child element matching the specified name
0338: Element childElement = (Element) parentElement.selectNodes(
0339: "./" + elementName).get(0);
0340: // return the value of the child element
0341: return childElement.getTextTrim();
0342: } catch (Exception e) {
0343: return null;
0344: }
0345: }
0346:
0347: /**
0348: * @see org.opencms.importexport.I_CmsImport#matches(org.opencms.importexport.CmsImportParameters)
0349: */
0350: public boolean matches(CmsImportParameters parameters)
0351: throws CmsImportExportException {
0352:
0353: // try to read the export version number
0354: CmsImportHelper helper = new CmsImportHelper(parameters);
0355: try {
0356: helper.openFile();
0357: // read the xml-config file
0358: Document docXml = CmsXmlUtils
0359: .unmarshalHelper(
0360: helper
0361: .getFileBytes(CmsImportExportManager.EXPORT_MANIFEST),
0362: null, false);
0363:
0364: return getVersion() == Integer.parseInt(((Element) docXml
0365: .selectNodes(
0366: "//" + CmsImportExportManager.N_VERSION)
0367: .get(0)).getTextTrim());
0368: } catch (IOException e) {
0369: CmsMessageContainer message = Messages
0370: .get()
0371: .container(
0372: Messages.ERR_IMPORTEXPORT_ERROR_OPENING_ZIP_ARCHIVE_1,
0373: parameters.getPath());
0374: if (LOG.isDebugEnabled()) {
0375: LOG.debug(message.key(), e);
0376: }
0377:
0378: throw new CmsImportExportException(message, e);
0379: } catch (Exception e) {
0380: // ignore the exception, the export file has no version number (version 0)
0381: // should never happen
0382: if (LOG.isErrorEnabled()) {
0383: LOG.error(e.getLocalizedMessage(), e);
0384: }
0385: } finally {
0386: helper.closeFile();
0387: }
0388: return false;
0389: }
0390:
0391: /**
0392: * Checks if the resources is in the list of immutalbe resources. <p>
0393: *
0394: * @param translatedName the name of the resource
0395: * @param immutableResources the list of the immutable resources
0396: * @return true or false
0397: */
0398: protected boolean checkImmutable(String translatedName,
0399: List immutableResources) {
0400:
0401: boolean resourceNotImmutable = true;
0402: if (immutableResources.contains(translatedName)) {
0403: if (LOG.isDebugEnabled()) {
0404: LOG
0405: .debug(Messages
0406: .get()
0407: .getBundle()
0408: .key(
0409: Messages.LOG_IMPORTEXPORT_RESOURCENAME_IMMUTABLE_1,
0410: translatedName));
0411: }
0412: // this resource must not be modified by an import if it already exists
0413: String storedSiteRoot = m_cms.getRequestContext()
0414: .getSiteRoot();
0415: try {
0416: m_cms.getRequestContext().setSiteRoot("/");
0417: m_cms.readResource(translatedName);
0418: resourceNotImmutable = false;
0419: if (LOG.isDebugEnabled()) {
0420: LOG
0421: .debug(Messages
0422: .get()
0423: .getBundle()
0424: .key(
0425: Messages.LOG_IMPORTEXPORT_IMMUTABLE_FLAG_SET_1,
0426: translatedName));
0427: }
0428: } catch (CmsException e) {
0429: // resourceNotImmutable will be true
0430: if (LOG.isDebugEnabled()) {
0431: LOG
0432: .debug(
0433: Messages
0434: .get()
0435: .getBundle()
0436: .key(
0437: Messages.LOG_IMPORTEXPORT_ERROR_ON_TEST_IMMUTABLE_1,
0438: translatedName), e);
0439: }
0440: } finally {
0441: m_cms.getRequestContext().setSiteRoot(storedSiteRoot);
0442: }
0443: }
0444: return resourceNotImmutable;
0445: }
0446:
0447: /**
0448: * Cleans up member variables after the import is finished.<p>
0449: *
0450: * This is required since there is only one instance for
0451: * each import version that is kept in memory and reused.<p>
0452: */
0453: protected void cleanUp() {
0454:
0455: m_importResource = null;
0456: m_importZip = null;
0457: m_report = null;
0458: m_linkStorage = null;
0459: m_linkPropertyStorage = null;
0460: m_groupsToCreate = null;
0461: m_cms = null;
0462: }
0463:
0464: /**
0465: * Converts old style pointers to siblings if possible.<p>
0466: */
0467: protected void convertPointerToSiblings() {
0468:
0469: try {
0470: int linksSize = m_linkStorage.size();
0471: int i = 0;
0472: Iterator itEntries = m_linkStorage.entrySet().iterator();
0473: // loop through all links to convert
0474: while (itEntries.hasNext()) {
0475: Map.Entry entry = (Map.Entry) itEntries.next();
0476:
0477: String key = (String) entry.getKey();
0478: String link = (String) entry.getValue();
0479: List properties = (List) m_linkPropertyStorage.get(key);
0480: CmsProperty.setAutoCreatePropertyDefinitions(
0481: properties, true);
0482:
0483: i++;
0484: m_report
0485: .print(
0486: org.opencms.report.Messages
0487: .get()
0488: .container(
0489: org.opencms.report.Messages.RPT_SUCCESSION_2,
0490: String.valueOf(i),
0491: String
0492: .valueOf(linksSize)),
0493: I_CmsReport.FORMAT_NOTE);
0494: m_report.print(Messages.get().container(
0495: Messages.RPT_CONVERT_LINK_0),
0496: I_CmsReport.FORMAT_NOTE);
0497: m_report
0498: .print(org.opencms.report.Messages
0499: .get()
0500: .container(
0501: org.opencms.report.Messages.RPT_ARGUMENT_1,
0502: key + " "));
0503: m_report
0504: .print(org.opencms.report.Messages
0505: .get()
0506: .container(
0507: org.opencms.report.Messages.RPT_DOTS_0));
0508:
0509: try {
0510: // check if this is an internal pointer
0511: if (link.startsWith("/")) {
0512: // check if the pointer target is existing
0513: CmsResource target = m_cms.readResource(link);
0514:
0515: // create a new sibling as CmsResource
0516: CmsResource resource = new CmsResource(
0517: new CmsUUID(), // structure ID is always a new UUID
0518: target.getResourceId(), key,
0519: target.getTypeId(),
0520: target.isFolder(),
0521: 0,
0522: m_cms.getRequestContext()
0523: .currentProject().getUuid(), // TODO: pass flags from import
0524: CmsResource.STATE_NEW, target
0525: .getDateCreated(), target
0526: .getUserCreated(), target
0527: .getDateLastModified(), target
0528: .getUserLastModified(),
0529: CmsResource.DATE_RELEASED_DEFAULT,
0530: CmsResource.DATE_EXPIRED_DEFAULT, 1, 0,
0531: target.getDateContent(), 0);
0532:
0533: m_cms.importResource(key, resource, null,
0534: properties);
0535: m_report
0536: .println(
0537: org.opencms.report.Messages
0538: .get()
0539: .container(
0540: org.opencms.report.Messages.RPT_OK_0),
0541: I_CmsReport.FORMAT_OK);
0542:
0543: if (LOG.isInfoEnabled()) {
0544: LOG
0545: .info(Messages
0546: .get()
0547: .getBundle()
0548: .key(
0549: Messages.LOG_CONVERT_LINK_DOTS_OK_3,
0550: String.valueOf(i),
0551: String
0552: .valueOf(linksSize),
0553: key));
0554: }
0555: } else {
0556: m_cms.createResource(key,
0557: CmsResourceTypePointer
0558: .getStaticTypeId(), link
0559: .getBytes(), properties);
0560: m_report
0561: .println(
0562: org.opencms.report.Messages
0563: .get()
0564: .container(
0565: org.opencms.report.Messages.RPT_OK_0),
0566: I_CmsReport.FORMAT_OK);
0567:
0568: if (LOG.isInfoEnabled()) {
0569: LOG.info(Messages.get().getBundle().key(
0570: Messages.LOG_CONVERT_LINK_OK_3,
0571: String.valueOf(i),
0572: String.valueOf(linksSize), key));
0573: }
0574: }
0575: } catch (CmsException e) {
0576: m_report.println();
0577: m_report
0578: .print(
0579: Messages
0580: .get()
0581: .container(
0582: Messages.RPT_CONVERT_LINK_NOTFOUND_1,
0583: link),
0584: I_CmsReport.FORMAT_WARNING);
0585:
0586: if (LOG.isErrorEnabled()) {
0587: LOG
0588: .error(
0589: Messages
0590: .get()
0591: .getBundle()
0592: .key(
0593: Messages.ERR_IMPORTEXPORT_LINK_CONVERSION_FAILED_2,
0594: key, link), e);
0595: }
0596: }
0597: }
0598: } finally {
0599: if (m_linkStorage != null) {
0600: m_linkStorage.clear();
0601: }
0602: m_linkStorage = null;
0603:
0604: if (m_linkPropertyStorage != null) {
0605: m_linkPropertyStorage.clear();
0606: }
0607: m_linkPropertyStorage = null;
0608: }
0609: }
0610:
0611: /**
0612: * Returns a byte array containing the content of the file.<p>
0613: *
0614: * @param filename the name of the file to read
0615: * @return a byte array containing the content of the file
0616: */
0617: protected byte[] getFileBytes(String filename) {
0618:
0619: try {
0620: // is this a zip-file?
0621: if (m_importZip != null) {
0622: // yes
0623: ZipEntry entry = m_importZip.getEntry(filename);
0624:
0625: // path to file might be relative, too
0626: if ((entry == null) && filename.startsWith("/")) {
0627: entry = m_importZip.getEntry(filename.substring(1));
0628: }
0629: if (entry == null) {
0630: throw new ZipException(
0631: Messages
0632: .get()
0633: .getBundle()
0634: .key(
0635: Messages.LOG_IMPORTEXPORT_FILE_NOT_FOUND_IN_ZIP_1,
0636: filename));
0637: }
0638:
0639: InputStream stream = m_importZip.getInputStream(entry);
0640: int size = new Long(entry.getSize()).intValue();
0641: return CmsFileUtil.readFully(stream, size);
0642: } else {
0643: // no - use directory
0644: File file = new File(m_importResource, filename);
0645: return CmsFileUtil.readFile(file);
0646: }
0647: } catch (FileNotFoundException fnfe) {
0648: if (LOG.isErrorEnabled()) {
0649: LOG.error(Messages.get().getBundle().key(
0650: Messages.ERR_IMPORTEXPORT_FILE_NOT_FOUND_1,
0651: filename), fnfe);
0652: }
0653: m_report.println(fnfe);
0654: } catch (IOException ioe) {
0655: if (LOG.isErrorEnabled()) {
0656: LOG.error(Messages.get().getBundle().key(
0657: Messages.ERR_IMPORTEXPORT_ERROR_READING_FILE_1,
0658: filename), ioe);
0659: }
0660: m_report.println(ioe);
0661: }
0662: // this will only be returned in case there was an exception
0663: return "".getBytes();
0664: }
0665:
0666: /**
0667: * Creates a new access control entry and stores it for later write out.
0668: *
0669: * @param res the resource
0670: * @param id the id of the principal
0671: * @param allowed the allowed permissions
0672: * @param denied the denied permissions
0673: * @param flags the flags
0674: *
0675: * @return the created ACE
0676: */
0677: protected CmsAccessControlEntry getImportAccessControlEntry(
0678: CmsResource res, String id, String allowed, String denied,
0679: String flags) {
0680:
0681: return new CmsAccessControlEntry(res.getResourceId(),
0682: new CmsUUID(id), Integer.parseInt(allowed), Integer
0683: .parseInt(denied), Integer.parseInt(flags));
0684: }
0685:
0686: /**
0687: * Returns the appropriate locale for the given destination.<p>
0688: *
0689: * @param destination the destination path (parent must exist)
0690: * @param properties the properties to check at first
0691: *
0692: * @return the locale
0693: */
0694: protected Locale getLocale(String destination, List properties) {
0695:
0696: String localeName = CmsProperty.get(
0697: CmsPropertyDefinition.PROPERTY_LOCALE, properties)
0698: .getValue();
0699:
0700: if (localeName != null) {
0701: // locale was already set on the files properties
0702: return (Locale) OpenCms.getLocaleManager()
0703: .getAvailableLocales(localeName).get(0);
0704: }
0705: // locale not set in properties, read default locales
0706: return (Locale) OpenCms.getLocaleManager().getDefaultLocales(
0707: m_cms, CmsResource.getParentFolder(destination)).get(0);
0708: }
0709:
0710: /**
0711: * Writes already imported access control entries for a given resource.<p>
0712: *
0713: * @param resource the resource assigned to the access control entries
0714: * @param aceList the access control entries to create
0715: */
0716: protected void importAccessControlEntries(CmsResource resource,
0717: List aceList) {
0718:
0719: if (aceList.size() == 0) {
0720: // no ACE in the list
0721: return;
0722: }
0723: try {
0724: m_cms.importAccessControlEntries(resource, aceList);
0725: } catch (CmsException exc) {
0726: m_report.println(Messages.get().container(
0727: Messages.RPT_IMPORT_ACL_DATA_FAILED_0),
0728: I_CmsReport.FORMAT_WARNING);
0729: }
0730: }
0731:
0732: /**
0733: * Imports a single group.<p>
0734: *
0735: * @param name the name of the group
0736: * @param description group description
0737: * @param flags group flags
0738: * @param parentgroupName name of the parent group
0739: *
0740: * @throws CmsImportExportException if something goes wrong
0741: */
0742: protected void importGroup(String name, String description,
0743: String flags, String parentgroupName)
0744: throws CmsImportExportException {
0745:
0746: if (description == null) {
0747: description = "";
0748: }
0749:
0750: CmsGroup parentGroup = null;
0751: try {
0752: if (CmsStringUtil.isNotEmpty(parentgroupName)) {
0753: try {
0754: parentGroup = m_cms.readGroup(parentgroupName);
0755: } catch (CmsException exc) {
0756: // parentGroup will be null
0757: }
0758: }
0759:
0760: if (CmsStringUtil.isNotEmpty(parentgroupName)
0761: && (parentGroup == null)) {
0762: // cannot create group, put on stack and try to create later
0763: Map groupData = new HashMap();
0764: groupData.put(A_CmsImport.N_NAME, name);
0765: groupData.put(A_CmsImport.N_DESCRIPTION, description);
0766: groupData.put(A_CmsImport.N_FLAGS, flags);
0767: groupData.put(A_CmsImport.N_PARENTGROUP,
0768: parentgroupName);
0769: m_groupsToCreate.push(groupData);
0770: } else {
0771: try {
0772: m_report.print(Messages.get().container(
0773: Messages.RPT_IMPORT_GROUP_0),
0774: I_CmsReport.FORMAT_NOTE);
0775: m_report
0776: .print(org.opencms.report.Messages
0777: .get()
0778: .container(
0779: org.opencms.report.Messages.RPT_ARGUMENT_1,
0780: name));
0781: m_report
0782: .print(org.opencms.report.Messages
0783: .get()
0784: .container(
0785: org.opencms.report.Messages.RPT_DOTS_0));
0786: m_cms.createGroup(name, description, Integer
0787: .parseInt(flags), parentgroupName);
0788: m_report
0789: .println(
0790: org.opencms.report.Messages
0791: .get()
0792: .container(
0793: org.opencms.report.Messages.RPT_OK_0),
0794: I_CmsReport.FORMAT_OK);
0795: } catch (CmsException exc) {
0796:
0797: m_report.println(Messages.get().container(
0798: Messages.RPT_NOT_CREATED_0),
0799: I_CmsReport.FORMAT_OK);
0800: }
0801: }
0802:
0803: } catch (Exception e) {
0804:
0805: m_report.println(e);
0806:
0807: CmsMessageContainer message = Messages.get().container(
0808: Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_GROUP_1,
0809: name);
0810: if (LOG.isDebugEnabled()) {
0811: LOG.debug(message.key(), e);
0812: }
0813: throw new CmsImportExportException(message, e);
0814: }
0815: }
0816:
0817: /**
0818: * Imports the OpenCms groups.<p>
0819: *
0820: * @throws CmsImportExportException if something goes wrong
0821: */
0822: protected void importGroups() throws CmsImportExportException {
0823:
0824: List groupNodes;
0825: Element currentElement;
0826: String name, description, flags, parentgroup;
0827: try {
0828: // getAll group nodes
0829: groupNodes = m_docXml.selectNodes("//"
0830: + A_CmsImport.N_GROUPDATA);
0831: // walk through all groups in manifest
0832: for (int i = 0; i < groupNodes.size(); i++) {
0833: currentElement = (Element) groupNodes.get(i);
0834: name = getChildElementTextValue(currentElement,
0835: A_CmsImport.N_NAME);
0836: name = OpenCms.getImportExportManager().translateGroup(
0837: name);
0838: description = getChildElementTextValue(currentElement,
0839: A_CmsImport.N_DESCRIPTION);
0840: flags = getChildElementTextValue(currentElement,
0841: A_CmsImport.N_FLAGS);
0842: parentgroup = getChildElementTextValue(currentElement,
0843: A_CmsImport.N_PARENTGROUP);
0844: if ((parentgroup != null) && (parentgroup.length() > 0)) {
0845: parentgroup = OpenCms.getImportExportManager()
0846: .translateGroup(parentgroup);
0847: }
0848: // import this group
0849:
0850: importGroup(name, description, flags, parentgroup);
0851: }
0852:
0853: // now try to import the groups in the stack
0854: while (!m_groupsToCreate.empty()) {
0855: Stack tempStack = m_groupsToCreate;
0856: m_groupsToCreate = new Stack();
0857: while (tempStack.size() > 0) {
0858: Map groupdata = (HashMap) tempStack.pop();
0859: name = (String) groupdata.get(A_CmsImport.N_NAME);
0860: description = (String) groupdata
0861: .get(A_CmsImport.N_DESCRIPTION);
0862: flags = (String) groupdata.get(A_CmsImport.N_FLAGS);
0863: parentgroup = (String) groupdata
0864: .get(A_CmsImport.N_PARENTGROUP);
0865: // try to import the group
0866: importGroup(name, description, flags, parentgroup);
0867: }
0868: }
0869: } catch (CmsImportExportException e) {
0870:
0871: throw e;
0872: } catch (Exception e) {
0873:
0874: m_report.println(e);
0875:
0876: CmsMessageContainer message = Messages.get().container(
0877: Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_GROUPS_0);
0878: if (LOG.isDebugEnabled()) {
0879: LOG.debug(message.key(), e);
0880: }
0881:
0882: throw new CmsImportExportException(message, e);
0883: }
0884: }
0885:
0886: /**
0887: * Imports a single user.<p>
0888: *
0889: * @param name user name
0890: * @param flags user flags
0891: * @param password user password
0892: * @param firstname firstname of the user
0893: * @param lastname lastname of the user
0894: * @param email user email
0895: * @param dateCreated creation date
0896: * @param userInfo user info
0897: * @param userGroups user groups
0898: *
0899: * @throws CmsImportExportException in case something goes wrong
0900: */
0901: protected void importUser(String name, String flags,
0902: String password, String firstname, String lastname,
0903: String email, long dateCreated, Map userInfo,
0904: List userGroups) throws CmsImportExportException {
0905:
0906: // create a new user id
0907: String id = new CmsUUID().toString();
0908: try {
0909: try {
0910: m_report.print(Messages.get().container(
0911: Messages.RPT_IMPORT_USER_0),
0912: I_CmsReport.FORMAT_NOTE);
0913: m_report
0914: .print(org.opencms.report.Messages
0915: .get()
0916: .container(
0917: org.opencms.report.Messages.RPT_ARGUMENT_1,
0918: name));
0919: m_report
0920: .print(org.opencms.report.Messages
0921: .get()
0922: .container(
0923: org.opencms.report.Messages.RPT_DOTS_0));
0924: m_cms.importUser(id, name, password, firstname,
0925: lastname, email, Integer.parseInt(flags),
0926: dateCreated, userInfo);
0927: // add user to all groups list
0928: for (int i = 0; i < userGroups.size(); i++) {
0929: String groupName = (String) userGroups.get(i);
0930: try {
0931: CmsGroup group = m_cms.readGroup(groupName);
0932: if (group.isVirtual() || group.isRole()) {
0933: CmsRole role = CmsRole.valueOf(group);
0934: OpenCms.getRoleManager().addUserToRole(
0935: m_cms, role, name);
0936: } else {
0937: m_cms.addUserToGroup(name, groupName);
0938: }
0939: } catch (CmsException exc) {
0940: m_report
0941: .println(
0942: Messages
0943: .get()
0944: .container(
0945: Messages.RPT_USER_COULDNT_BE_ADDED_TO_GROUP_2,
0946: name, groupName),
0947: I_CmsReport.FORMAT_WARNING);
0948: if (LOG.isDebugEnabled()) {
0949: LOG.debug(exc.getLocalizedMessage(), exc);
0950: }
0951: }
0952: }
0953: m_report.println(
0954: org.opencms.report.Messages.get().container(
0955: org.opencms.report.Messages.RPT_OK_0),
0956: I_CmsReport.FORMAT_OK);
0957: } catch (CmsException exc) {
0958: m_report.println(Messages.get().container(
0959: Messages.RPT_NOT_CREATED_0),
0960: I_CmsReport.FORMAT_OK);
0961: }
0962: } catch (Exception e) {
0963:
0964: m_report.println(e);
0965:
0966: CmsMessageContainer message = Messages.get().container(
0967: Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_USER_1,
0968: name);
0969: if (LOG.isDebugEnabled()) {
0970: LOG.debug(message.key(), e);
0971: }
0972: throw new CmsImportExportException(message, e);
0973: }
0974: }
0975:
0976: /**
0977: * Imports the OpenCms users.<p>
0978: *
0979: * @throws CmsImportExportException if something goes wrong
0980: */
0981: protected void importUsers() throws CmsImportExportException {
0982:
0983: List userNodes;
0984: List groupNodes;
0985: List userGroups;
0986: Element currentElement, currentGroup;
0987: Map userInfo = new HashMap();
0988: String name, description, flags, password, firstname, lastname, email, address, pwd, infoNode, defaultGroup;
0989: // try to get the import resource
0990: //getImportResource();
0991: try {
0992: // getAll user nodes
0993: userNodes = m_docXml.selectNodes("//"
0994: + A_CmsImport.N_USERDATA);
0995: // walk threw all groups in manifest
0996: for (int i = 0; i < userNodes.size(); i++) {
0997: currentElement = (Element) userNodes.get(i);
0998: name = getChildElementTextValue(currentElement,
0999: A_CmsImport.N_NAME);
1000: name = OpenCms.getImportExportManager().translateUser(
1001: name);
1002: // decode passwords using base 64 decoder
1003: pwd = getChildElementTextValue(currentElement,
1004: A_CmsImport.N_PASSWORD);
1005: password = new String(Base64.decodeBase64(pwd.trim()
1006: .getBytes()));
1007: description = getChildElementTextValue(currentElement,
1008: A_CmsImport.N_DESCRIPTION);
1009: flags = getChildElementTextValue(currentElement,
1010: A_CmsImport.N_FLAGS);
1011: firstname = getChildElementTextValue(currentElement,
1012: A_CmsImport.N_FIRSTNAME);
1013: lastname = getChildElementTextValue(currentElement,
1014: A_CmsImport.N_LASTNAME);
1015: email = getChildElementTextValue(currentElement,
1016: A_CmsImport.N_EMAIL);
1017: address = getChildElementTextValue(currentElement,
1018: A_CmsImport.N_TAG_ADDRESS);
1019: defaultGroup = getChildElementTextValue(currentElement,
1020: A_CmsImport.N_DEFAULTGROUP);
1021: // get the userinfo and put it into the additional info map
1022: infoNode = getChildElementTextValue(currentElement,
1023: A_CmsImport.N_USERINFO);
1024: try {
1025: // read the userinfo from the dat-file
1026: byte[] value = getFileBytes(infoNode);
1027: // deserialize the object
1028: ByteArrayInputStream bin = new ByteArrayInputStream(
1029: value);
1030: ObjectInputStream oin = new ObjectInputStream(bin);
1031: userInfo = (Map) oin.readObject();
1032: } catch (IOException ioex) {
1033: m_report.println(ioex);
1034: } catch (ClassCastException ccex) {
1035: m_report.println(ccex);
1036: } catch (ClassNotFoundException cnfex) {
1037: m_report.println(cnfex);
1038: }
1039:
1040: // get the groups of the user and put them into the list
1041: groupNodes = currentElement.selectNodes("*/"
1042: + A_CmsImport.N_GROUPNAME);
1043: userGroups = new ArrayList();
1044: for (int j = 0; j < groupNodes.size(); j++) {
1045: currentGroup = (Element) groupNodes.get(j);
1046: String userInGroup = getChildElementTextValue(
1047: currentGroup, A_CmsImport.N_NAME);
1048: userInGroup = OpenCms.getImportExportManager()
1049: .translateGroup(userInGroup);
1050: userGroups.add(userInGroup);
1051: }
1052:
1053: if (CmsStringUtil.isNotEmpty(defaultGroup)) {
1054: userInfo
1055: .put(
1056: CmsUserSettings.ADDITIONAL_INFO_DEFAULTGROUP,
1057: defaultGroup);
1058: }
1059:
1060: if (description != null) {
1061: userInfo
1062: .put(
1063: CmsUserSettings.ADDITIONAL_INFO_DESCRIPTION,
1064: description);
1065: }
1066: if (address != null) {
1067: userInfo.put(
1068: CmsUserSettings.ADDITIONAL_INFO_ADDRESS,
1069: address);
1070: }
1071: // import this user
1072: importUser(name, flags, password, firstname, lastname,
1073: email, 0, userInfo, userGroups);
1074: }
1075: } catch (CmsImportExportException e) {
1076: throw e;
1077: } catch (Exception e) {
1078: m_report.println(e);
1079: CmsMessageContainer message = Messages.get().container(
1080: Messages.ERR_IMPORTEXPORT_ERROR_IMPORTING_USERS_0);
1081: if (LOG.isDebugEnabled()) {
1082: LOG.debug(message.key(), e);
1083: }
1084: throw new CmsImportExportException(message, e);
1085: }
1086: }
1087:
1088: /**
1089: * Initializes all member variables before the import is started.<p>
1090: *
1091: * This is required since there is only one instance for
1092: * each import version that is kept in memory and reused.<p>
1093: */
1094: protected void initialize() {
1095:
1096: m_groupsToCreate = new Stack();
1097: }
1098:
1099: /**
1100: * Reads all properties below a specified parent element from the <code>manifest.xml</code>.<p>
1101: *
1102: * @param parentElement the current file node
1103: * @param ignoredPropertyKeys a list of properties to be ignored
1104: *
1105: * @return a list with all properties
1106: */
1107: protected List readPropertiesFromManifest(Element parentElement,
1108: List ignoredPropertyKeys) {
1109:
1110: // all imported Cms property objects are collected in map first forfaster access
1111: Map properties = new HashMap();
1112: CmsProperty property = null;
1113: List propertyElements = parentElement.selectNodes("./"
1114: + A_CmsImport.N_PROPERTIES + "/"
1115: + A_CmsImport.N_PROPERTY);
1116: Element propertyElement = null;
1117: String key = null, value = null;
1118: Attribute attrib = null;
1119:
1120: // iterate over all property elements
1121: for (int i = 0, n = propertyElements.size(); i < n; i++) {
1122: propertyElement = (Element) propertyElements.get(i);
1123: key = getChildElementTextValue(propertyElement,
1124: A_CmsImport.N_NAME);
1125:
1126: if ((key == null) || ignoredPropertyKeys.contains(key)) {
1127: // continue if the current property (key) should be ignored or is null
1128: continue;
1129: }
1130:
1131: // all Cms properties are collected in a map keyed by their property keys
1132: property = (CmsProperty) properties.get(key);
1133: if (property == null) {
1134: property = new CmsProperty();
1135: property.setName(key);
1136: property.setAutoCreatePropertyDefinition(true);
1137: properties.put(key, property);
1138: }
1139:
1140: value = getChildElementTextValue(propertyElement,
1141: A_CmsImport.N_VALUE);
1142: if (value == null) {
1143: value = "";
1144: }
1145:
1146: attrib = propertyElement
1147: .attribute(A_CmsImport.N_PROPERTY_ATTRIB_TYPE);
1148: if ((attrib != null)
1149: && attrib.getValue().equals(
1150: A_CmsImport.N_PROPERTY_ATTRIB_TYPE_SHARED)) {
1151: // it is a shared/resource property value
1152: property.setResourceValue(value);
1153: } else {
1154: // it is an individual/structure value
1155: property.setStructureValue(value);
1156: }
1157: }
1158:
1159: return new ArrayList(properties.values());
1160: }
1161: }
|