0001: /*
0002: * The contents of this file are subject to the
0003: * Mozilla Public License Version 1.1 (the "License");
0004: * you may not use this file except in compliance with the License.
0005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
0006: *
0007: * Software distributed under the License is distributed on an "AS IS"
0008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
0009: * See the License for the specific language governing rights and
0010: * limitations under the License.
0011: *
0012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
0013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
0014: *
0015: * All Rights Reserved.
0016: *
0017: * Contributor(s):
0018: */
0019:
0020: package org.openharmonise.dav.server.utils;
0021:
0022: import java.io.*;
0023: import java.net.*;
0024: import java.util.*;
0025: import java.util.logging.*;
0026:
0027: import org.openharmonise.commons.dsi.AbstractDataStoreInterface;
0028: import org.openharmonise.commons.xml.namespace.NamespaceType;
0029: import org.openharmonise.rm.*;
0030: import org.openharmonise.rm.config.*;
0031: import org.openharmonise.rm.factory.*;
0032: import org.openharmonise.rm.metadata.*;
0033: import org.openharmonise.rm.resources.*;
0034: import org.openharmonise.rm.resources.audit.*;
0035: import org.openharmonise.rm.resources.content.*;
0036: import org.openharmonise.rm.resources.metadata.properties.*;
0037: import org.openharmonise.rm.resources.metadata.values.*;
0038: import org.openharmonise.rm.resources.publishing.*;
0039: import org.openharmonise.rm.resources.users.*;
0040: import org.openharmonise.rm.resources.workflow.properties.*;
0041: import org.openharmonise.rm.resources.workflow.values.*;
0042: import org.openharmonise.rm.resources.xml.*;
0043: import org.openharmonise.rm.security.authorization.*;
0044: import org.openharmonise.rm.workflow.WorkflowProfile;
0045:
0046: import com.ibm.webdav.*;
0047:
0048: /**
0049: * This class deals with the resolving of resource names and paths from DAV to
0050: * Harmonise and vice versa.
0051: *
0052: * @author Michael Bell
0053: * @version $Revision: 1.6 $
0054: *
0055: */
0056: public class HarmoniseNameResolver {
0057:
0058: public static final String PNAME_AUTO_APPROVE_COLLECTIONS = "AUTO_APPROVE_COLLECTIONS";
0059:
0060: // TODO change hard coded root to a configurable mechanism
0061: public static final String WEBDAV_ROOT_MARKER = "webdav";
0062: public static final String URL_SEPARATOR = "/";
0063: public static final String UTF_8 = "UTF-8";
0064: private static final String VERSION_SEGMENT = "ver";
0065:
0066: public static final String RESOURCE_TYPE_VALUE = "value";
0067: public static final String RESOURCE_TYPE_RESOURCE = "resource";
0068: public static final String RESOURCE_TYPE_PROPERTY = "property-resource";
0069: public static final String RESOURCE_TYPE_COLLECTION = "collection";
0070:
0071: public static final String CONTENT_NAME = "Content";
0072: public static final String WEBSITE_NAME = "Website";
0073: public static final String COMPOSITION_NAME = WEBSITE_NAME
0074: + "/Composition";
0075: public static final String METADATA_NAME = "Metadata";
0076: public static final String ARCHIVE_NAME = "Archive";
0077: public static final String ASSETS_NAME = CONTENT_NAME + "/Assets";
0078: public static final String ASSETS_PATH = "/root/assets";
0079: public static final String REPORTS_NAME = "Reports";
0080: public static final String REPORTS_PATH = "/root/reports";
0081: public static final String DOCS_NAME = CONTENT_NAME + "/Documents";
0082: public static final String DOCS_PATH = "/root/documents";
0083: public static final String NEWSLETTER_NAME = "Newsletter";
0084: public static final String NEWSLETTER_PATH = "/root/newsletter";
0085: public static final String PROPERTY_NAME = METADATA_NAME
0086: + "/Properties";
0087: public static final String PROPERTY_PATH = "/root/props";
0088: public static final String VALUE_NAME = METADATA_NAME + "/Values";
0089: public static final String VALUE_PATH = "/root/vals";
0090: public static final String WEBPAGES_NAME = WEBSITE_NAME
0091: + "/Page Definition";
0092: public static final String WEBPAGES_PATH = "/root";
0093: public static final String O_TEMPLATES_NAME = COMPOSITION_NAME
0094: + "/Object Templates";
0095: public static final String O_TEMPLATES_PATH = "/root";
0096: public static final String P_TEMPLATES_NAME = COMPOSITION_NAME
0097: + "/Page Templates";
0098: public static final String P_TEMPLATES_PATH = "/root/pages";
0099: public static final String INCLUDES_NAME = COMPOSITION_NAME
0100: + "/Includes";
0101: public static final String INCLUDES_PATH = "/root/includes";
0102: public static final String USERS_NAME = "Users";
0103: public static final String USERS_PATH = "/root";
0104: public static final String DISPLAY_NAME = WEBSITE_NAME + "/Display";
0105: public static final String XSLT_NAME = DISPLAY_NAME + "/XSLT";
0106: public static final String XSLT_PATH = "/root";
0107: public static final String SITE_ASSETS_NAME = WEBSITE_NAME
0108: + "/Site Assets";
0109: public static final String SITE_ASSETS_PATH = "/root/site assets";
0110: public static final String RBS_PROPS_NAME = "RBS_PROPS";
0111: public static final String RBS_PROPS_PATH = "/root/rbs";
0112: public static final String RBS_VALS_NAME = "RBS_VALS";
0113: public static final String RBS_VALS_PATH = "/root/rbs";
0114: public static final String SYSTEM_PROPS_NAME = "SYSTEM_PROPS";
0115: public static final String SYSTEM_PROPS_PATH = "/root/system";
0116: public static final String WORKFLOW_PROPS_NAME = "WORKFLOW_PROPS";
0117: public static final String WORKFLOW_PROPS_PATH = "/root/workflow";
0118: public static final String WORKFLOW_DEFS_NAME = "WORKFLOW_DEFS";
0119: public static final String WORKFLOW_DEFS_PATH = "/root/workflow_defs";
0120: public static final String WORKFLOW_STAGES_NAME = "WORKFLOW_STAGES";
0121: public static final String WORKFLOW_STAGES_PATH = "/root/workflow_stages";
0122:
0123: public static final String ROOT_NAME = "root";
0124: public static final String ROOT_PATH = "/root";
0125:
0126: private static Map URI_2_CLASS_MAPPINGS = new Hashtable();
0127: private static Map CONTENT_HARMONISE_PATH_MAPPINGS = new Hashtable();
0128: private static Map TYPE_MAPPINGS = new Hashtable();
0129:
0130: private static Map m_liveprop2XML_map = new Hashtable();
0131: private static Map m_rootSections_map = new Hashtable();
0132: private static Map m_histObjects_map = new Hashtable();
0133: private static Map m_rootGroupMappings = new Hashtable();
0134:
0135: private static Map CLASS_2_RESOURCE_TYPE_MAPPING = new Hashtable();
0136: private static Document m_histDoc = null;
0137: private static Section m_histSec = null;
0138: private static Asset m_histAsset = null;
0139: private static List ROOT_GROUPS = new Vector();
0140: private static Map ROOT_COLLECTION_DESCS = new Hashtable();
0141: private static Map CLASS_2_GROUPOBJECT = new Hashtable();
0142:
0143: public static final String START_PROP_NAME = "START";
0144:
0145: /**
0146: * Logger for this class
0147: */
0148: private static final Logger m_logger = Logger
0149: .getLogger(HarmoniseNameResolver.class.getName());
0150:
0151: public static final String VIRTUAL_RESOURCE_NAME = ".resource";
0152: public static final String VIRTUAL_COLLECTION_NAME = ".collection";
0153:
0154: static {
0155: //content desc
0156: DAVCollectionDesc content = new DAVCollectionDesc(CONTENT_NAME,
0157: true);
0158:
0159: List content_members = new Vector();
0160: content_members.add(DOCS_NAME);
0161: content_members.add(ASSETS_NAME);
0162: content.addMembers(content_members);
0163:
0164: ROOT_COLLECTION_DESCS.put(CONTENT_NAME, content);
0165:
0166: //website desc
0167: DAVCollectionDesc website = new DAVCollectionDesc(WEBSITE_NAME,
0168: true);
0169:
0170: List website_members = new Vector();
0171: website_members.add(COMPOSITION_NAME);
0172: website_members.add(DISPLAY_NAME);
0173: website_members.add(SITE_ASSETS_NAME);
0174: website_members.add(WEBPAGES_NAME);
0175: website.addMembers(website_members);
0176:
0177: ROOT_COLLECTION_DESCS.put(WEBSITE_NAME, website);
0178:
0179: //users desc
0180: DAVCollectionDesc users = new DAVCollectionDesc(USERS_NAME,
0181: USERS_PATH, UserGroup.class.getName());
0182:
0183: ROOT_COLLECTION_DESCS.put(USERS_NAME, users);
0184:
0185: //newsletter desc
0186: DAVCollectionDesc newsletter = new DAVCollectionDesc(
0187: NEWSLETTER_NAME, NEWSLETTER_PATH, Section.class
0188: .getName());
0189: ROOT_COLLECTION_DESCS.put(NEWSLETTER_NAME, newsletter);
0190:
0191: //reports desc
0192: DAVCollectionDesc reports = new DAVCollectionDesc(REPORTS_NAME,
0193: REPORTS_PATH, XMLAuditResourceGroup.class.getName());
0194: ROOT_COLLECTION_DESCS.put(REPORTS_NAME, reports);
0195:
0196: //metadata desc
0197: DAVCollectionDesc metadata = new DAVCollectionDesc(
0198: METADATA_NAME, true);
0199:
0200: List metamembers = new Vector();
0201: metamembers.add(PROPERTY_NAME);
0202: metamembers.add(VALUE_NAME);
0203: metadata.addMembers(metamembers);
0204: ROOT_COLLECTION_DESCS.put(METADATA_NAME, metadata);
0205:
0206: //composition desc
0207: DAVCollectionDesc composition = new DAVCollectionDesc(
0208: COMPOSITION_NAME, true);
0209:
0210: List comp_members = new Vector();
0211:
0212: comp_members.add(O_TEMPLATES_NAME);
0213: comp_members.add(P_TEMPLATES_NAME);
0214: comp_members.add(INCLUDES_NAME);
0215:
0216: composition.addMembers(comp_members);
0217:
0218: ROOT_COLLECTION_DESCS.put(COMPOSITION_NAME, composition);
0219:
0220: //docs desc
0221: DAVCollectionDesc docs = new DAVCollectionDesc(DOCS_NAME,
0222: DOCS_PATH, Section.class.getName());
0223:
0224: ROOT_COLLECTION_DESCS.put(DOCS_NAME, docs);
0225:
0226: //assets desc
0227: DAVCollectionDesc assets = new DAVCollectionDesc(ASSETS_NAME,
0228: ASSETS_PATH, Section.class.getName());
0229:
0230: ROOT_COLLECTION_DESCS.put(ASSETS_NAME, assets);
0231:
0232: //display desc
0233: DAVCollectionDesc display = new DAVCollectionDesc(DISPLAY_NAME,
0234: true);
0235:
0236: List disp_members = new Vector();
0237:
0238: disp_members.add(XSLT_NAME);
0239:
0240: display.addMembers(disp_members);
0241:
0242: ROOT_COLLECTION_DESCS.put(DISPLAY_NAME, display);
0243:
0244: //site assets desc
0245: DAVCollectionDesc site_assets = new DAVCollectionDesc(
0246: SITE_ASSETS_NAME, SITE_ASSETS_PATH, Section.class
0247: .getName());
0248:
0249: ROOT_COLLECTION_DESCS.put(SITE_ASSETS_NAME, site_assets);
0250:
0251: //web pages desc
0252: DAVCollectionDesc pages = new DAVCollectionDesc(WEBPAGES_NAME,
0253: WEBPAGES_PATH, WebPageGroup.class.getName());
0254:
0255: ROOT_COLLECTION_DESCS.put(WEBPAGES_NAME, pages);
0256:
0257: //property desc
0258: DAVCollectionDesc prop = new DAVCollectionDesc(PROPERTY_NAME,
0259: PROPERTY_PATH, PropertyGroup.class.getName());
0260:
0261: ROOT_COLLECTION_DESCS.put(PROPERTY_NAME, prop);
0262:
0263: //value desc
0264: DAVCollectionDesc vals = new DAVCollectionDesc(VALUE_NAME,
0265: VALUE_PATH, ValueGroup.class.getName());
0266:
0267: ROOT_COLLECTION_DESCS.put(VALUE_NAME, vals);
0268:
0269: //obj templates desc
0270: DAVCollectionDesc obj_temps = new DAVCollectionDesc(
0271: O_TEMPLATES_NAME, O_TEMPLATES_PATH, TemplateGroup.class
0272: .getName());
0273:
0274: ROOT_COLLECTION_DESCS.put(O_TEMPLATES_NAME, obj_temps);
0275:
0276: //page templates desc
0277: DAVCollectionDesc page_temps = new DAVCollectionDesc(
0278: P_TEMPLATES_NAME, P_TEMPLATES_PATH,
0279: XMLResourceGroup.class.getName());
0280:
0281: ROOT_COLLECTION_DESCS.put(P_TEMPLATES_NAME, page_temps);
0282:
0283: //includes desc
0284: DAVCollectionDesc includes = new DAVCollectionDesc(
0285: INCLUDES_NAME, INCLUDES_PATH, XMLResourceGroup.class
0286: .getName());
0287:
0288: ROOT_COLLECTION_DESCS.put(INCLUDES_NAME, includes);
0289:
0290: //xslt desc
0291: DAVCollectionDesc xslts = new DAVCollectionDesc(XSLT_NAME,
0292: XSLT_PATH, XSLResourceGroup.class.getName());
0293:
0294: ROOT_COLLECTION_DESCS.put(XSLT_NAME, xslts);
0295:
0296: //rbs props
0297: DAVCollectionDesc rbs_props = new DAVCollectionDesc(
0298: RBS_PROPS_NAME, RBS_PROPS_PATH, PropertyGroup.class
0299: .getName());
0300: ROOT_COLLECTION_DESCS.put(RBS_PROPS_NAME, rbs_props);
0301:
0302: //rbs_vals
0303: DAVCollectionDesc rbs_vals = new DAVCollectionDesc(
0304: RBS_VALS_NAME, RBS_VALS_PATH, ValueGroup.class
0305: .getName());
0306: ROOT_COLLECTION_DESCS.put(RBS_VALS_NAME, rbs_vals);
0307:
0308: //system props
0309: DAVCollectionDesc sys_props = new DAVCollectionDesc(
0310: SYSTEM_PROPS_NAME, SYSTEM_PROPS_PATH,
0311: PropertyGroup.class.getName());
0312: ROOT_COLLECTION_DESCS.put(SYSTEM_PROPS_NAME, sys_props);
0313:
0314: //workflow props
0315: DAVCollectionDesc wrkflw_props = new DAVCollectionDesc(
0316: WORKFLOW_PROPS_NAME, WORKFLOW_PROPS_PATH,
0317: WorkflowPropertyGroup.class.getName());
0318: ROOT_COLLECTION_DESCS.put(WORKFLOW_PROPS_NAME, wrkflw_props);
0319:
0320: //workflow defs
0321: DAVCollectionDesc wrkflw_defs = new DAVCollectionDesc(
0322: WORKFLOW_DEFS_NAME, WORKFLOW_DEFS_PATH,
0323: WorkflowStageValueGroup.class.getName());
0324: ROOT_COLLECTION_DESCS.put(WORKFLOW_DEFS_NAME, wrkflw_defs);
0325:
0326: //workflow stages
0327: DAVCollectionDesc wrkflw_stages = new DAVCollectionDesc(
0328: WORKFLOW_STAGES_NAME, WORKFLOW_STAGES_PATH,
0329: WorkflowStageValueGroup.class.getName());
0330: ROOT_COLLECTION_DESCS.put(WORKFLOW_STAGES_NAME, wrkflw_stages);
0331:
0332: TYPE_MAPPINGS.put("Document", Document.class.getName());
0333: TYPE_MAPPINGS.put("Asset", Asset.class.getName());
0334: TYPE_MAPPINGS.put("Section", Section.class.getName());
0335: TYPE_MAPPINGS.put("User", User.class.getName());
0336: TYPE_MAPPINGS.put("UserGroup", UserGroup.class.getName());
0337: TYPE_MAPPINGS.put("Value", Value.class.getName());
0338: TYPE_MAPPINGS.put("ValueGroup", ValueGroup.class.getName());
0339: TYPE_MAPPINGS.put("Property", Property.class.getName());
0340: TYPE_MAPPINGS.put("PropertyGroup", PropertyGroup.class
0341: .getName());
0342: TYPE_MAPPINGS.put("Template", Template.class.getName());
0343: TYPE_MAPPINGS.put("TemplateGroup", TemplateGroup.class
0344: .getName());
0345: TYPE_MAPPINGS.put("WebPage", WebPage.class.getName());
0346: TYPE_MAPPINGS.put("WebPageGroup", WebPageGroup.class.getName());
0347: TYPE_MAPPINGS.put("XSLResourceGroup", XSLResourceGroup.class
0348: .getName());
0349: TYPE_MAPPINGS.put("XSLResource", XSLResource.class.getName());
0350: TYPE_MAPPINGS.put("XMLResourceGroup", XMLResourceGroup.class
0351: .getName());
0352: TYPE_MAPPINGS.put("XMLResource", XMLResource.class.getName());
0353: TYPE_MAPPINGS.put("XMLAuditResourceGroup",
0354: XMLAuditResourceGroup.class.getName());
0355: TYPE_MAPPINGS.put("XMLAuditResource", XMLAuditResource.class
0356: .getName());
0357: TYPE_MAPPINGS.put("WorkflowStageValueGroup",
0358: WorkflowStageValueGroup.class.getName());
0359: TYPE_MAPPINGS.put("WorkflowStageValue",
0360: WorkflowStageValue.class.getName());
0361: TYPE_MAPPINGS.put("WorkflowProperty", WorkflowProperty.class
0362: .getName());
0363: TYPE_MAPPINGS.put("WorkflowPropertyGroup",
0364: WorkflowProperty.class.getName());
0365:
0366: ROOT_GROUPS.add(CONTENT_NAME);
0367: ROOT_GROUPS.add(WEBSITE_NAME);
0368: ROOT_GROUPS.add(USERS_NAME);
0369: ROOT_GROUPS.add(NEWSLETTER_NAME);
0370: ROOT_GROUPS.add(REPORTS_NAME);
0371: //ROOT_GROUPS.add(ARCHIVE_NAME);
0372: ROOT_GROUPS.add(METADATA_NAME);
0373: ROOT_GROUPS.add(WORKFLOW_DEFS_NAME);
0374: ROOT_GROUPS.add(WORKFLOW_STAGES_NAME);
0375: ROOT_GROUPS.add(WORKFLOW_PROPS_NAME);
0376:
0377: CLASS_2_RESOURCE_TYPE_MAPPING.put(Document.class.getName(),
0378: RESOURCE_TYPE_RESOURCE);
0379: CLASS_2_RESOURCE_TYPE_MAPPING.put(Value.class.getName(),
0380: RESOURCE_TYPE_VALUE);
0381: CLASS_2_RESOURCE_TYPE_MAPPING.put(Property.class.getName(),
0382: RESOURCE_TYPE_RESOURCE);
0383: CLASS_2_RESOURCE_TYPE_MAPPING.put(Asset.class.getName(),
0384: RESOURCE_TYPE_RESOURCE);
0385: CLASS_2_RESOURCE_TYPE_MAPPING.put(User.class.getName(),
0386: RESOURCE_TYPE_RESOURCE);
0387: CLASS_2_RESOURCE_TYPE_MAPPING.put(Template.class.getName(),
0388: RESOURCE_TYPE_RESOURCE);
0389: CLASS_2_RESOURCE_TYPE_MAPPING.put(WebPage.class.getName(),
0390: RESOURCE_TYPE_RESOURCE);
0391: }
0392:
0393: public HarmoniseNameResolver() {
0394: }
0395:
0396: /** Translate a URL into a Harmonise path name.
0397: *
0398: * @param url the URL of the resource
0399: * @return the translated pathname
0400: */
0401: public static String getRealPath(URL url)
0402: throws NameResolverException {
0403:
0404: String sPath = null;
0405: try {
0406: sPath = URLDecoder.decode(url.getFile(), UTF_8);
0407: } catch (UnsupportedEncodingException e) {
0408: throw new NameResolverException(e);
0409: }
0410:
0411: return getRealPath(sPath);
0412: }
0413:
0414: /**
0415: * Returns the name of the resource referenced by the given
0416: * <code>URL</code>. Effectively returns the last segment of the
0417: * given URI.
0418: *
0419: * @param url the reosurce URL
0420: * @return the name of the resource
0421: * @throws UnsupportedEncodingException if an error occurs decoding
0422: * the URI
0423: */
0424: public static String getResourceName(URL url)
0425: throws UnsupportedEncodingException {
0426: String sResourceName = null;
0427:
0428: String sResourcePath = URLDecoder.decode(url.getPath(),
0429: HarmoniseNameResolver.UTF_8);
0430:
0431: sResourceName = HarmoniseNameResolver
0432: .getLastSegment(sResourcePath);
0433:
0434: return sResourceName;
0435: }
0436:
0437: /** Translate a URL into a Harmonise path name.
0438: *
0439: * @param url the URL of the resource
0440: * @return the translated pathname
0441: */
0442: public static String getRealPath(String sPath)
0443: throws NameResolverException {
0444:
0445: if (m_logger.isLoggable(Level.FINE)) {
0446: m_logger
0447: .log(Level.FINE, "getRealPath: url file - " + sPath);
0448: }
0449:
0450: String pathName = null;
0451: int nIndex = sPath.indexOf(WEBDAV_ROOT_MARKER);
0452:
0453: if (nIndex >= 0) {
0454: nIndex = sPath.indexOf('/', nIndex + 1);
0455:
0456: if (nIndex >= 0) {
0457: pathName = sPath.substring(nIndex + 1);
0458: } else {
0459: throw new NameResolverException("Invalid URI given - "
0460: + sPath);
0461: }
0462: } else {
0463: throw new NameResolverException("Invalid URI given - "
0464: + sPath);
0465: }
0466:
0467: Iterator iter = ROOT_COLLECTION_DESCS.values().iterator();
0468: boolean bFound = false;
0469:
0470: while (iter.hasNext() == true && bFound == false) {
0471: DAVCollectionDesc desc = (DAVCollectionDesc) iter.next();
0472: if (desc.isVirtual() == false) {
0473:
0474: String sColURI = desc.getURI();
0475:
0476: if (pathName.startsWith(sColURI) == true) {
0477: bFound = true;
0478: if (pathName.equals(sColURI) == true) {
0479: pathName = desc.getHarmonisePath();
0480: } else {
0481:
0482: String sAdd = pathName.substring(sColURI
0483: .length() + 1);
0484:
0485: StringBuffer strbuf = new StringBuffer();
0486:
0487: strbuf.append(desc.getHarmonisePath());
0488:
0489: if (sAdd != null && sAdd.length() > 0) {
0490: strbuf.append(URL_SEPARATOR).append(sAdd);
0491: }
0492:
0493: pathName = strbuf.toString();
0494:
0495: }
0496:
0497: }
0498: }
0499: }
0500:
0501: if (m_logger.isLoggable(Level.FINE)) {
0502: m_logger.log(Level.FINE, "Returning path - " + pathName);
0503: }
0504:
0505: return pathName;
0506: }
0507:
0508: /**
0509: * Returns the URI that the given object can be accessed by over WebDAV.
0510: *
0511: * @param cobj
0512: * @return
0513: * @throws Exception
0514: */
0515: public static String getDAVPath(AbstractChildObject cobj)
0516: throws NameResolverException {
0517: String sPath = null;
0518:
0519: if (cobj != null) {
0520: try {
0521: sPath = cobj.getFullPath();
0522: } catch (DataAccessException e) {
0523:
0524: try {
0525: throw new NameResolverException("Problem with "
0526: + cobj.getName(), e);
0527: } catch (DataAccessException e1) {
0528: throw new NameResolverException(e);
0529: }
0530: }
0531:
0532: sPath = getDAVPath(cobj.getClass(), sPath);
0533: }
0534:
0535: return sPath;
0536: }
0537:
0538: /**
0539: * Returns the DAV path equivalent of a Harmonise path.
0540: *
0541: * Note: it's more efficent to use the <code>getDAVPath</code>
0542: * which takes both the class and the Harmonise path.
0543: *
0544: * @param dsi
0545: * @param harmonisePath
0546: * @return
0547: * @throws NameResolverException
0548: */
0549: public static String getDAVPath(AbstractDataStoreInterface dsi,
0550: String harmonisePath) throws NameResolverException {
0551: Iterator iter = ROOT_COLLECTION_DESCS.values().iterator();
0552: String sDAVVirtDirName = null;
0553: String sDavMapOHRoot = null;
0554: boolean bFound = false;
0555:
0556: while (iter.hasNext() && bFound == false) {
0557: DAVCollectionDesc desc = (DAVCollectionDesc) iter.next();
0558:
0559: if (desc.isVirtual() == false
0560: && harmonisePath
0561: .startsWith(desc.getHarmonisePath())) {
0562: String sClass = desc.getHarmoniseClass();
0563:
0564: try {
0565: AbstractChildObject child = (AbstractChildObject) HarmoniseObjectFactory
0566: .instantiateHarmoniseObject(dsi, sClass,
0567: harmonisePath);
0568:
0569: if (child != null && child.exists() == true) {
0570: bFound = true;
0571: sDAVVirtDirName = desc.getURI();
0572: sDavMapOHRoot = desc.getHarmonisePath();
0573: } else {
0574: AbstractParentObject parent = (AbstractParentObject) HarmoniseObjectFactory
0575: .instantiateHarmoniseObject(dsi,
0576: sClass,
0577: getPathParent(harmonisePath));
0578:
0579: if (parent != null && parent.exists()) {
0580: child = parent
0581: .getChildByName(getLastSegment(harmonisePath));
0582:
0583: if (child != null) {
0584: bFound = true;
0585: sDAVVirtDirName = desc.getURI();
0586: sDavMapOHRoot = desc.getHarmonisePath();
0587: }
0588: }
0589:
0590: }
0591:
0592: } catch (HarmoniseFactoryException e) {
0593: m_logger.log(Level.WARNING,
0594: e.getLocalizedMessage(), e);
0595: } catch (DataAccessException e) {
0596: m_logger.log(Level.WARNING,
0597: e.getLocalizedMessage(), e);
0598: }
0599: }
0600: }
0601: String sResult = null;
0602:
0603: if (bFound == true) {
0604: StringBuffer sDAVpath = new StringBuffer();
0605:
0606: sDAVpath.append(URL_SEPARATOR).append(WEBDAV_ROOT_MARKER)
0607: .append(URL_SEPARATOR);
0608:
0609: if (sDavMapOHRoot == null || sDAVVirtDirName == null) {
0610: throw new NameResolverException(
0611: "Problem getting DAV path from "
0612: + sDavMapOHRoot + " and "
0613: + sDAVVirtDirName);
0614: }
0615: sDAVpath.append(harmonisePath.replaceFirst(sDavMapOHRoot,
0616: sDAVVirtDirName));
0617:
0618: if (m_logger.isLoggable(Level.FINE)) {
0619: m_logger.log(Level.FINE, "Harmonise path - "
0620: + harmonisePath + ", dav path - " + sDAVpath);
0621:
0622: }
0623:
0624: sResult = sDAVpath.toString();
0625:
0626: }
0627:
0628: return sResult;
0629: }
0630:
0631: /**
0632: * Returns the URI that the given object can be accessed by over WebDAV.
0633: *
0634: * @param clss
0635: * @param sHarmonisePath
0636: * @return
0637: * @throws NameResolverException
0638: */
0639: public static String getDAVPath(Class clss, String sHarmonisePath)
0640: throws NameResolverException {
0641:
0642: if (m_logger.isLoggable(Level.FINE)) {
0643: m_logger.log(Level.FINE, "getDAVPath: class name - "
0644: + clss.getName() + " path - " + sHarmonisePath);
0645: }
0646:
0647: if (clss.isAssignableFrom(AbstractParentObject.class) == false) {
0648: //is a child object class - need to find parent
0649:
0650: String sGroupObjectClassName = (String) CLASS_2_GROUPOBJECT
0651: .get(clss.getName());
0652:
0653: if (sGroupObjectClassName == null) {
0654:
0655: try {
0656: AbstractChildObject child = (AbstractChildObject) clss
0657: .newInstance();
0658:
0659: sGroupObjectClassName = child
0660: .getParentObjectClassName();
0661:
0662: CLASS_2_GROUPOBJECT.put(clss.getName(),
0663: sGroupObjectClassName);
0664: } catch (InstantiationException e) {
0665: m_logger.log(Level.WARNING,
0666: e.getLocalizedMessage(), e);
0667: } catch (IllegalAccessException e) {
0668: m_logger.log(Level.WARNING,
0669: e.getLocalizedMessage(), e);
0670: }
0671: }
0672:
0673: try {
0674: clss = Class.forName(sGroupObjectClassName);
0675: } catch (ClassNotFoundException e) {
0676:
0677: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
0678: }
0679: }
0680:
0681: Iterator iter = ROOT_COLLECTION_DESCS.values().iterator();
0682: String sDAVVirtDirName = null;
0683: String sDavMapOHRoot = null;
0684: boolean bFound = false;
0685: while (iter.hasNext() && bFound == false) {
0686: DAVCollectionDesc desc = (DAVCollectionDesc) iter.next();
0687:
0688: if (clss.getName().equals(desc.getHarmoniseClass())
0689: && sHarmonisePath.startsWith(desc
0690: .getHarmonisePath())) {
0691: sDAVVirtDirName = desc.getURI();
0692: sDavMapOHRoot = desc.getHarmonisePath();
0693: bFound = true;
0694: }
0695: }
0696:
0697: StringBuffer sDAVpath = new StringBuffer();
0698:
0699: sDAVpath.append(URL_SEPARATOR).append(WEBDAV_ROOT_MARKER)
0700: .append(URL_SEPARATOR);
0701:
0702: if (sDavMapOHRoot == null || sDAVVirtDirName == null) {
0703: throw new NameResolverException(
0704: "Problem getting DAV path from " + sDavMapOHRoot
0705: + " and " + sDAVVirtDirName);
0706: }
0707: sDAVpath.append(sHarmonisePath.replaceFirst(sDavMapOHRoot,
0708: sDAVVirtDirName));
0709:
0710: if (m_logger.isLoggable(Level.FINE)) {
0711: m_logger.log(Level.FINE, "Harmonise path - "
0712: + sHarmonisePath + ", dav path - " + sDAVpath);
0713:
0714: }
0715:
0716: return sDAVpath.toString();
0717: }
0718:
0719: /**
0720: * Returns the version path to a specific version of a resource
0721: *
0722: * @param child
0723: * @return
0724: * @throws NameResolverException
0725: */
0726: public static String getVersionPath(AbstractChildObject child)
0727: throws NameResolverException {
0728:
0729: int nId = -1;
0730: int nKey = -1;
0731: try {
0732: AbstractChildObject live = (AbstractChildObject) child
0733: .getLiveVersion();
0734: if (live != null) {
0735: nId = live.getId();
0736: } else {
0737: nId = child.getId();
0738: }
0739:
0740: nKey = child.getKey();
0741: } catch (DataAccessException e) {
0742: throw new NameResolverException(e);
0743: }
0744:
0745: String sClass = child.getClass().getName();
0746: String sType = sClass.substring(sClass.lastIndexOf(".") + 1);
0747:
0748: StringBuffer strbuf = new StringBuffer();
0749:
0750: strbuf.append(URL_SEPARATOR).append(WEBDAV_ROOT_MARKER).append(
0751: URL_SEPARATOR);
0752: strbuf.append(sType).append(URL_SEPARATOR);
0753: strbuf.append(String.valueOf(nId)).append(URL_SEPARATOR)
0754: .append(VERSION_SEGMENT).append(URL_SEPARATOR);
0755: strbuf.append(String.valueOf(nKey));
0756:
0757: return strbuf.toString();
0758: }
0759:
0760: /**
0761: * Returns the full URL for the given child object.
0762: *
0763: * @param cobj
0764: * @param resourceUrl
0765: * @return
0766: */
0767: public static String getFullURL(AbstractChildObject cobj,
0768: URL resourceUrl) throws NameResolverException {
0769: StringBuffer sURL = new StringBuffer();
0770:
0771: sURL.append(resourceUrl.getProtocol());
0772: sURL.append("://");
0773: sURL.append(resourceUrl.getHost());
0774: sURL.append(":");
0775: sURL.append(resourceUrl.getPort());
0776: sURL.append(getDAVPath(cobj));
0777:
0778: return sURL.toString();
0779: }
0780:
0781: /**
0782: * Returns a Universal Unique Identifier for the combination of URI and user name.
0783: *
0784: * @param uri
0785: * @param user_name
0786: * @return
0787: * @throws NameResolverException
0788: */
0789: public static String getUUID(String uri, String user_name)
0790: throws NameResolverException {
0791: String uuid_base;
0792: try {
0793: uuid_base = URLDecoder.decode(uri, UTF_8) + user_name;
0794: } catch (UnsupportedEncodingException e) {
0795: throw new NameResolverException(e);
0796: }
0797:
0798: if (m_logger.isLoggable(Level.FINE)) {
0799: m_logger.log(Level.FINE, "getUUID: uri - " + uri
0800: + ", user - " + user_name);
0801: m_logger.log(Level.FINE, "getUUID: UUID - " + uuid_base);
0802: }
0803:
0804: return String.valueOf(uuid_base.hashCode());
0805: }
0806:
0807: public static String getTagForLiveProperty(String livepropname) {
0808: return (String) m_liveprop2XML_map.get(livepropname);
0809: }
0810:
0811: public static boolean isMappedLiveProperty(String livepropname) {
0812: return m_liveprop2XML_map.containsKey(livepropname);
0813: }
0814:
0815: public static String getResourceType(String sResourceName) {
0816: int nDotIndex = sResourceName.indexOf(".");
0817: String sExt = "";
0818:
0819: if (nDotIndex > 0) {
0820: sExt = sResourceName.substring(nDotIndex);
0821: }
0822:
0823: return sExt;
0824: }
0825:
0826: /**
0827: * Returns <code>true</code> if the given URL path is a version path of the form
0828: * 'http://..../../4/ver/23' where 4 would be the live id of a versioned resource
0829: * and 23 would be the key of the specific version.
0830: *
0831: * @param sPath
0832: * @return
0833: */
0834: public static boolean isVersionPath(String sPath) {
0835: boolean bIsVersion = false;
0836:
0837: int nIndex = sPath.lastIndexOf(URL_SEPARATOR + VERSION_SEGMENT
0838: + URL_SEPARATOR);
0839:
0840: if (nIndex > 0) {
0841: bIsVersion = true;
0842: String sLastSeg = getLastSegment(sPath);
0843:
0844: if (m_logger.isLoggable(Level.FINE)) {
0845: m_logger.log(Level.FINE, "Is a number? - " + sLastSeg);
0846: }
0847:
0848: try {
0849: int nKey = Integer.parseInt(sLastSeg);
0850: } catch (NumberFormatException e) {
0851: bIsVersion = false;
0852: }
0853: }
0854:
0855: if (m_logger.isLoggable(Level.FINE)) {
0856: m_logger.log(Level.FINE, sPath + " is a version path:"
0857: + bIsVersion);
0858: }
0859:
0860: return bIsVersion;
0861: }
0862:
0863: /**
0864: * Returns <code>true</code> if URL is a path to an archived version.
0865: *
0866: * @param sURL
0867: * @return
0868: */
0869: public static boolean isArchiveURL(URL url) {
0870: return isArchiveURL(url.getPath());
0871: }
0872:
0873: /**
0874: * Returns <code>true</code> if URL is a path to an archived version.
0875: *
0876: * @param sURL
0877: * @return
0878: */
0879: public static boolean isArchiveURL(String sURL) {
0880:
0881: boolean bIsArchive = (sURL.indexOf(URL_SEPARATOR
0882: + WEBDAV_ROOT_MARKER + URL_SEPARATOR + ARCHIVE_NAME) >= 0);
0883:
0884: if (m_logger.isLoggable(Level.FINE)) {
0885: m_logger.log(Level.FINE, "Checking for archive - " + sURL
0886: + " - " + bIsArchive);
0887: }
0888:
0889: return bIsArchive;
0890: }
0891:
0892: /**
0893: * Returns the path to a file on the local file system associated to the
0894: * given URL.
0895: *
0896: * @param url
0897: * @return
0898: * @throws Exception
0899: */
0900: public static String getFilePath(URL url)
0901: throws NameResolverException {
0902: String sResult = null;
0903:
0904: String sName = url.getFile();
0905: sName = sName.substring(sName.lastIndexOf(URL_SEPARATOR) + 1);
0906:
0907: try {
0908: StringBuffer sbuf = new StringBuffer();
0909:
0910: sbuf.append(ConfigSettings
0911: .getProperty("UPLOADED_TEMPFILE_DIR"));
0912:
0913: if (sbuf.toString().endsWith(File.separator) == false) {
0914: sbuf.append(File.separator);
0915: }
0916:
0917: sbuf.append(sName);
0918:
0919: sResult = sbuf.toString();
0920: } catch (ConfigException e) {
0921: throw new NameResolverException(e);
0922: }
0923: return sResult;
0924: }
0925:
0926: /**
0927: * Returns a child object from the given URL.
0928: *
0929: * @param dsi
0930: * @param url
0931: * @return
0932: * @throws NameResolverException
0933: */
0934: public static AbstractChildObject getObjectFromURL(
0935: AbstractDataStoreInterface dsi, URL url)
0936: throws NameResolverException {
0937: String sPath = null;
0938: try {
0939: sPath = URLDecoder.decode(url.getFile(), UTF_8);
0940: } catch (UnsupportedEncodingException e) {
0941: throw new NameResolverException(e);
0942: }
0943:
0944: return getObjectFromURL(dsi, sPath);
0945: }
0946:
0947: /**
0948: * Returns a child object from the given URL.
0949: *
0950: * @param dsi
0951: * @param sPath
0952: * @return
0953: * @throws NameResolverException
0954: */
0955: public static AbstractChildObject getObjectFromURL(
0956: AbstractDataStoreInterface dsi, String sPath)
0957: throws NameResolverException {
0958: AbstractChildObject child = null;
0959: try {
0960: sPath = URLDecoder.decode(sPath, UTF_8);
0961: } catch (UnsupportedEncodingException e) {
0962: throw new NameResolverException(e);
0963: }
0964: if (isVersionPath(sPath) == true) {
0965: child = getObjectFromVersionURL(dsi, sPath);
0966: } else if (isArchiveURL(sPath) == true) {
0967: child = getArchivedObject(dsi, sPath);
0968: } else {
0969: child = getObjectFromNonVersionURL(dsi, sPath);
0970: }
0971:
0972: return child;
0973: }
0974:
0975: /**
0976: * Returns a child object from the given non-version URL.
0977: *
0978: * @param dsi
0979: * @param sPath
0980: * @return
0981: * @throws NameResolverException
0982: */
0983: public static AbstractChildObject getObjectFromNonVersionURL(
0984: AbstractDataStoreInterface dsi, String sPath)
0985: throws NameResolverException {
0986: AbstractChildObject child = null;
0987:
0988: if (isVersionPath(sPath) == true) {
0989: throw new InvalidPathException("Invalid path");
0990: }
0991:
0992: if (m_logger.isLoggable(Level.FINE)) {
0993: m_logger.log(Level.FINE, "dealing with path - " + sPath);
0994: }
0995:
0996: String sParentType = getParentTypeFromURL(sPath);
0997:
0998: if (m_logger.isLoggable(Level.FINE)) {
0999: m_logger.log(Level.FINE, "parent type - " + sParentType);
1000: }
1001:
1002: if (sParentType != null) {
1003: String ohPath = getRealPath(sPath);
1004:
1005: if (m_logger.isLoggable(Level.FINE)) {
1006: m_logger.log(Level.FINE, "real path - " + ohPath);
1007: }
1008:
1009: try {
1010: if (ohPath.equals(ROOT_PATH) == true) {
1011: child = (AbstractParentObject) HarmoniseObjectFactory
1012: .instantiatePublishableObject(dsi,
1013: sParentType, ohPath);
1014:
1015: if (child == null) {
1016: throw new NameResolverException(
1017: "Didn't find root!");
1018: }
1019: } else {
1020: String ohParentPath = getPathParent(ohPath);
1021:
1022: AbstractParentObject parent = (AbstractParentObject) HarmoniseObjectFactory
1023: .instantiatePublishableObject(dsi,
1024: sParentType, ohParentPath);
1025:
1026: if (parent != null) {
1027: child = parent
1028: .getChildByName(getLastSegment(ohPath));
1029: } else {
1030: m_logger.logp(Level.INFO,
1031: HarmoniseNameResolver.class.getName(),
1032: "getObjectFromNonVersionURL",
1033: sParentType
1034: + " object not found for path "
1035: + ohParentPath);
1036: }
1037: }
1038: } catch (HarmoniseFactoryException e) {
1039: throw new NameResolverException(e);
1040: } catch (DataAccessException e) {
1041: throw new NameResolverException(e);
1042: }
1043: }
1044:
1045: return child;
1046: }
1047:
1048: /**
1049: * Returns a child object from a version URL.
1050: *
1051: * @param dsi
1052: * @param sPath
1053: * @return
1054: * @throws NameResolverException
1055: */
1056: public static AbstractChildObject getObjectFromVersionURL(
1057: AbstractDataStoreInterface dsi, String sPath)
1058: throws NameResolverException {
1059: AbstractChildObject child = null;
1060:
1061: if (isVersionPath(sPath) == false) {
1062: throw new InvalidPathException("Invalid path");
1063: }
1064:
1065: int nLastSep = sPath.lastIndexOf(URL_SEPARATOR);
1066:
1067: if (sPath.endsWith(URL_SEPARATOR)) {
1068: nLastSep = sPath.substring(0, nLastSep - 1).lastIndexOf(
1069: URL_SEPARATOR);
1070: }
1071:
1072: int nKey = Integer.parseInt(getLastSegment(sPath));
1073:
1074: int nPostIdSep = nLastSep - VERSION_SEGMENT.length()
1075: - URL_SEPARATOR.length();
1076:
1077: int nPreIdSep = sPath.substring(0, nPostIdSep).lastIndexOf(
1078: URL_SEPARATOR);
1079:
1080: String sLiveId = sPath.substring(nPreIdSep + 1, nPostIdSep);
1081:
1082: if (m_logger.isLoggable(Level.FINE)) {
1083: m_logger
1084: .log(Level.FINE, "looking for live id - " + sLiveId);
1085: }
1086:
1087: int nLiveId = Integer.parseInt(sLiveId);
1088:
1089: String sType = getTypeFromVersionURL(sPath);
1090:
1091: if (m_logger.isLoggable(Level.FINE)) {
1092: m_logger.log(Level.FINE, "Looking for " + sType
1093: + " live id = " + nLiveId + ", key = " + nKey);
1094: }
1095:
1096: try {
1097: AbstractChildObject liveChild = (AbstractChildObject) HarmoniseObjectFactory
1098: .instantiateHarmoniseObject(dsi, sType, nLiveId);
1099:
1100: if (liveChild == null) {
1101: if (m_logger.isLoggable(Level.INFO)) {
1102: m_logger.log(Level.INFO, "Live version in " + sPath
1103: + " not found!");
1104: }
1105: throw new InvalidPathException("Live version in "
1106: + sPath + " not found!");
1107: }
1108:
1109: //check live child exists as live
1110: if (liveChild.exists() == true) {
1111: int nLiveKey = liveChild.getKey();
1112:
1113: List versions = null;
1114:
1115: if (nLiveKey == nKey) {
1116: child = liveChild;
1117: } else {
1118:
1119: if (nLiveKey < nKey) {
1120: //if version key is greater than live key we're looking for a pending version
1121: versions = liveChild.getPendingVersions();
1122: } else if (nLiveKey > nKey) {
1123: //if version key is less than live key we're looking for a historical version
1124: versions = liveChild.getHistoricalVersions();
1125: }
1126:
1127: child = getChildByKeyFromList(versions, nKey);
1128:
1129: if (child == null) {
1130: //initial assumptions about key ordering were wrong
1131: //try again reversing assumptions
1132:
1133: if (nLiveKey < nKey) {
1134: //if version key is less than live key we're looking for a historical version
1135: versions = liveChild
1136: .getHistoricalVersions();
1137: } else if (nLiveKey > nKey) {
1138: //if version key is greater than live key we're looking for a pending version
1139: versions = liveChild.getPendingVersions();
1140: }
1141:
1142: child = getChildByKeyFromList(versions, nKey);
1143: }
1144: }
1145: } else {
1146: //must be historical
1147: child = (AbstractChildObject) Class.forName(sType)
1148: .newInstance();
1149: child.setId(nLiveId);
1150: child.setHistorical(true);
1151: child.setKey(nKey);
1152: child.setDataStoreInterface(dsi);
1153: }
1154: } catch (HarmoniseFactoryException e) {
1155: throw new NameResolverException(e);
1156: } catch (DataAccessException e) {
1157: throw new NameResolverException(e);
1158: } catch (InstantiationException e) {
1159: throw new NameResolverException(e);
1160: } catch (IllegalAccessException e) {
1161: throw new NameResolverException(e);
1162: } catch (ClassNotFoundException e) {
1163: throw new NameResolverException(e);
1164: } catch (PopulateException e) {
1165: throw new NameResolverException(e);
1166: }
1167:
1168: return child;
1169: }
1170:
1171: /**
1172: * Returns the archived child object reference by the given path.
1173: *
1174: * @param dsi
1175: * @param sPath
1176: * @return
1177: * @throws NameResolverException
1178: */
1179: public static AbstractChildObject getArchivedObject(
1180: AbstractDataStoreInterface dsi, String sPath)
1181: throws NameResolverException {
1182: AbstractChildObject child = null;
1183:
1184: if (isArchiveURL(sPath) == false) {
1185: throw new InvalidPathException("Invalid path");
1186: }
1187:
1188: try {
1189: AbstractParentObject parent = null;
1190: String sLivePath = sPath.replaceAll(URL_SEPARATOR
1191: + ARCHIVE_NAME, "");
1192:
1193: //first assume the parent will not be archived
1194: String sParentPath = getPathParent(sPath);
1195:
1196: String sLiveParentPath = sParentPath.replaceAll(
1197: URL_SEPARATOR + ARCHIVE_NAME, "");
1198:
1199: if (isVirtualCollection(sLiveParentPath) == true) {
1200: //if parent is virtual collection this is gonna be a live root collection
1201: if (m_logger.isLoggable(Level.FINE)) {
1202: m_logger.log(Level.FINE,
1203: "looking for virtual parent child - "
1204: + sLivePath);
1205: }
1206:
1207: if (isVirtualCollection(sLivePath) == false) {
1208: child = getObjectFromURL(dsi, sLivePath);
1209: }
1210: } else {
1211: if (m_logger.isLoggable(Level.FINE)) {
1212: m_logger.log(Level.FINE,
1213: "looking for live parent - "
1214: + sLiveParentPath);
1215: }
1216: //try and get live parent
1217: parent = (AbstractParentObject) getObjectFromURL(dsi,
1218: sLiveParentPath);
1219:
1220: if (parent == null) {
1221: //parent was archived too
1222: parent = (AbstractParentObject) getObjectFromURL(
1223: dsi, sParentPath);
1224: }
1225:
1226: String sName = getLastSegment(sPath);
1227:
1228: child = parent.getArchivedChildByName(sName);
1229:
1230: if (child == null) {
1231: child = parent.getChildByName(sName);
1232:
1233: //the live child must be a parent object to be part of the archive hiarchy
1234: if ((child instanceof AbstractParentObject) == false) {
1235: child = null;
1236: }
1237: }
1238: }
1239:
1240: } catch (DataAccessException e) {
1241: throw new NameResolverException(e);
1242: } catch (NameResolverException e) {
1243: throw new NameResolverException(e);
1244: }
1245:
1246: return child;
1247: }
1248:
1249: /**
1250: * Returns the key associated to the given value in the given map.
1251: *
1252: * @param val
1253: * @param map
1254: * @return
1255: */
1256: private static Object getKeyForValue(Object val, Map map) {
1257: Object result = null;
1258: Iterator iter = map.keySet().iterator();
1259:
1260: boolean bFound = false;
1261:
1262: while (iter.hasNext() == true && bFound == false) {
1263: Object key = iter.next();
1264: if (map.get(key).equals(val) == true) {
1265: bFound = true;
1266: result = key;
1267: }
1268: }
1269:
1270: return result;
1271: }
1272:
1273: /**
1274: * Returns the class name associated to the given URL of the resource, if the URL is
1275: * a version URL, or at least the resource type's group class name if the URL is a
1276: * standard DAV URL.
1277: *
1278: * @param sPath
1279: * @return
1280: * @throws NameResolverException
1281: */
1282: public static String getParentTypeFromURL(String sPath)
1283: throws NameResolverException {
1284: String sType = null;
1285:
1286: try {
1287: sPath = URLDecoder.decode(sPath, UTF_8);
1288: } catch (UnsupportedEncodingException e) {
1289: throw new NameResolverException(e.getLocalizedMessage(), e);
1290: }
1291:
1292: DAVCollectionDesc desc = null;
1293:
1294: String sSubPath = sPath.substring(sPath
1295: .indexOf(WEBDAV_ROOT_MARKER)
1296: + WEBDAV_ROOT_MARKER.length() + 1);
1297:
1298: if (m_logger.isLoggable(Level.FINE)) {
1299: m_logger.log(Level.FINE, "getParentTypeFromURL: sPath - "
1300: + sPath + ", sSubPath = " + sSubPath);
1301: }
1302:
1303: Iterator iter = ROOT_COLLECTION_DESCS.keySet().iterator();
1304:
1305: boolean bFound = false;
1306:
1307: int nKeyLength = 0;
1308:
1309: while (iter.hasNext()) {
1310: String sKey = (String) iter.next();
1311:
1312: if (m_logger.isLoggable(Level.FINER)) {
1313: m_logger.log(Level.FINER, "comparing " + sSubPath
1314: + " with " + sKey);
1315: }
1316:
1317: if (sSubPath.startsWith(sKey) && sKey.length() > nKeyLength) {
1318: bFound = true;
1319: desc = (DAVCollectionDesc) ROOT_COLLECTION_DESCS
1320: .get(sKey);
1321: nKeyLength = sKey.length();
1322: }
1323: }
1324:
1325: if (desc != null) {
1326: sType = desc.getHarmoniseClass();
1327: }
1328:
1329: return sType;
1330: }
1331:
1332: /**
1333: * Returns the class name associated to the given URL of the resource, if the URL is
1334: * a version URL, or at least the resource type's group class name if the URL is a
1335: * standard DAV URL.
1336: *
1337: * @param sPath
1338: * @return
1339: */
1340: public static String getTypeFromVersionURL(String sPath) {
1341: String sType = null;
1342:
1343: int nIndex = sPath.indexOf(WEBDAV_ROOT_MARKER);
1344:
1345: String sSubPath = sPath.substring(nIndex
1346: + WEBDAV_ROOT_MARKER.length() + 1);
1347:
1348: sSubPath = sSubPath.substring(0, sSubPath
1349: .indexOf(URL_SEPARATOR));
1350:
1351: Iterator iter = TYPE_MAPPINGS.keySet().iterator();
1352:
1353: boolean bFound = false;
1354:
1355: while (iter.hasNext() == true && bFound == false) {
1356: String sKey = (String) iter.next();
1357:
1358: if (sSubPath.equalsIgnoreCase(sKey) == true) {
1359: bFound = true;
1360: sType = (String) TYPE_MAPPINGS.get(sKey);
1361: }
1362: }
1363:
1364: return sType;
1365: }
1366:
1367: /**
1368: * Returns the class name associated to the given URL of the resource, if the URL is
1369: * a version URL, or at least the resource type's group class name if the URL is a
1370: * standard DAV URL.
1371: *
1372: * @param sPath
1373: * @return
1374: */
1375: public static String getChildTypeFromURL(String sPath)
1376: throws NameResolverException {
1377: String sReturnType = null;
1378:
1379: try {
1380: sPath = URLDecoder.decode(sPath, UTF_8);
1381: } catch (UnsupportedEncodingException e) {
1382: throw new NameResolverException(e.getLocalizedMessage(), e);
1383: }
1384:
1385: if (sPath.indexOf(ASSETS_NAME) > 0) {
1386: sReturnType = Asset.class.getName();
1387: } else if (sPath.indexOf(DOCS_NAME) > 0
1388: || sPath.indexOf(WEBDAV_ROOT_MARKER + URL_SEPARATOR
1389: + NEWSLETTER_NAME) > 0) {
1390: sReturnType = Document.class.getName();
1391: } else {
1392: //do the rest by finding the child class names from the parent class
1393:
1394: String sType = getParentTypeFromURL(sPath);
1395:
1396: try {
1397: AbstractParentObject parent = (AbstractParentObject) Class
1398: .forName(sType).newInstance();
1399:
1400: List childTypes = parent.getChildClassNames();
1401:
1402: List childNonParentTypes = new Vector();
1403:
1404: Iterator iter = childTypes.iterator();
1405:
1406: while (iter.hasNext()) {
1407: String className = (String) iter.next();
1408:
1409: if (className.equals(sType) == false) {
1410: sReturnType = className;
1411: }
1412: }
1413: } catch (InstantiationException e) {
1414: throw new NameResolverException(e);
1415: } catch (IllegalAccessException e) {
1416: throw new NameResolverException(e);
1417: } catch (ClassNotFoundException e) {
1418: throw new NameResolverException(e);
1419: }
1420: }
1421:
1422: return sReturnType;
1423: }
1424:
1425: /**
1426: * Returns the path of the parent of the object reference by the given path.
1427: *
1428: * @param sPath
1429: * @return
1430: */
1431: public static String getPathParent(String sPath) {
1432: String sParent = null;
1433:
1434: if (sPath.endsWith(URL_SEPARATOR)) {
1435: sPath = sPath.substring(0, sPath.length() - 1);
1436: }
1437:
1438: sParent = sPath.substring(0, sPath.lastIndexOf(URL_SEPARATOR));
1439:
1440: return sParent;
1441: }
1442:
1443: /**
1444: * Returns the path of the parent of the object reference by the given path.
1445: *
1446: * @param sPath
1447: * @return
1448: */
1449: public static String getLastSegment(String sPath) {
1450: String sParent = null;
1451:
1452: if (sPath != null) {
1453:
1454: if (sPath.endsWith(URL_SEPARATOR)) {
1455: sPath = sPath.substring(0, sPath.length() - 1);
1456: }
1457:
1458: sParent = sPath.substring(
1459: sPath.lastIndexOf(URL_SEPARATOR) + 1, sPath
1460: .length());
1461: }
1462:
1463: return sParent;
1464: }
1465:
1466: /**
1467: * Returns the member collections of the DAV root.
1468: *
1469: * @return
1470: */
1471: public static List getRootCollections() {
1472: return ROOT_GROUPS;
1473: }
1474:
1475: /**
1476: * Returns <code>true</code> if the given url references the root of the DAV server
1477: * i.e. http://.../webdav/
1478: *
1479: * @param url
1480: * @return
1481: */
1482: public static boolean isDAVRoot(URL url) {
1483: String sPath = url.getPath();
1484:
1485: return isDAVRoot(sPath);
1486: }
1487:
1488: /**
1489: * Returns <code>true</code> if the given url references the root of the DAV server
1490: * i.e. http://.../webdav/
1491: *
1492: * @param url
1493: * @return
1494: */
1495: public static boolean isDAVRoot(String sURL) {
1496: String sLastSegment = getLastSegment(sURL);
1497:
1498: return sLastSegment.equals(WEBDAV_ROOT_MARKER);
1499: }
1500:
1501: /**
1502: * Returns <code>true</code> if the given url references the archive root
1503: *
1504: * @param url
1505: * @return
1506: */
1507: public static boolean isArchiveRoot(URL url) {
1508: String sPath = url.getPath();
1509:
1510: return isArchiveRoot(sPath);
1511: }
1512:
1513: /**
1514: * Returns <code>true</code> if the given url references the archive root
1515: *
1516: * @param url
1517: * @return
1518: */
1519: public static boolean isArchiveRoot(String sPath) {
1520:
1521: if (sPath.endsWith(URL_SEPARATOR) == true) {
1522: sPath = sPath.substring(0, sPath.length() - 1);
1523: }
1524:
1525: return sPath.endsWith(WEBDAV_ROOT_MARKER + URL_SEPARATOR
1526: + ARCHIVE_NAME);
1527: }
1528:
1529: /**
1530: * Returns <code>true</code> if the given url references one of the virtual collections
1531: * i.e. a collection represented in the DAV hierarchy that doesn't have an equivalent
1532: * Harmonise parent object
1533: *
1534: * @param url
1535: * @return
1536: */
1537: public static boolean isVirtualCollection(URL url) {
1538:
1539: String sPath = url.getPath();
1540:
1541: try {
1542: sPath = URLDecoder.decode(sPath, UTF_8);
1543: } catch (UnsupportedEncodingException e) {
1544: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1545: }
1546:
1547: return isVirtualCollection(sPath);
1548: }
1549:
1550: /**
1551: * Returns <code>true</code> if the given url references a virtual resource
1552: * i.e. a non-existent resource representing collection resources.
1553: *
1554: * @param url
1555: * @return
1556: */
1557: public static boolean isVirtualResource(URL url) {
1558:
1559: String sPath = url.getPath();
1560:
1561: try {
1562: sPath = URLDecoder.decode(sPath, UTF_8);
1563: } catch (UnsupportedEncodingException e) {
1564: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1565: }
1566:
1567: return isVirtualResource(sPath);
1568: }
1569:
1570: /**
1571: * Returns <code>true</code> if the given path references a virtual resource
1572: * i.e. a non-existent resource representing collection resources.
1573: *
1574: * @param path
1575: * @return
1576: */
1577: private static boolean isVirtualResource(String path) {
1578: boolean bIsVirtual = false;
1579:
1580: String sLastSeg = getLastSegment(path);
1581:
1582: if (sLastSeg != null) {
1583: bIsVirtual = sLastSeg.equals(VIRTUAL_RESOURCE_NAME);
1584: }
1585:
1586: return bIsVirtual;
1587: }
1588:
1589: /**
1590: * Returns <code>true</code> if the given url references one of the virtual collections
1591: * i.e. a collection represented in the DAV hierarchy that doesn't have an equivalent
1592: * Harmonise parent object.
1593: *
1594: * @param url
1595: * @return
1596: */
1597: public static boolean isVirtualCollection(String sPath) {
1598: boolean bIsVirtual = false;
1599:
1600: bIsVirtual = isDAVRoot(sPath);
1601:
1602: if (bIsVirtual == false) {
1603: bIsVirtual = isArchiveRoot(sPath);
1604: }
1605:
1606: if (bIsVirtual == false) {
1607: String sLastSegment = getLastSegment(sPath);
1608:
1609: if (m_logger.isLoggable(Level.FINE)) {
1610: m_logger
1611: .log(Level.FINE,
1612: "Checking virtual collection - "
1613: + sLastSegment);
1614: }
1615:
1616: bIsVirtual = sLastSegment.equals(WEBDAV_ROOT_MARKER)
1617: || sLastSegment.equals(VIRTUAL_COLLECTION_NAME);
1618:
1619: //check against all descs if necessary
1620: if (bIsVirtual == false) {
1621: DAVCollectionDesc desc = getCollectionDesc(sPath);
1622:
1623: if (desc != null) {
1624: bIsVirtual = desc.isVirtual();
1625: }
1626: }
1627:
1628: if (m_logger.isLoggable(Level.FINE)) {
1629: m_logger.log(Level.FINE, "Is virtual collection - "
1630: + bIsVirtual);
1631: }
1632: }
1633:
1634: return bIsVirtual;
1635: }
1636:
1637: public static List getArchivedVirtualCollectionMemberNames(
1638: URL resourceURL) {
1639: List members = null;
1640:
1641: String sPath = resourceURL.getPath();
1642:
1643: if (isArchiveURL(sPath) == true) {
1644: sPath = sPath
1645: .replaceFirst(URL_SEPARATOR + ARCHIVE_NAME, "");
1646:
1647: members = getVirtualCollectionMemberNames(sPath);
1648: }
1649:
1650: return members;
1651: }
1652:
1653: public static List getVirtualCollectionMemberNames(URL url) {
1654: return getVirtualCollectionMemberNames(url.getPath());
1655: }
1656:
1657: /**
1658: * Returns the list of members for the virtual collection found at the given URL.
1659: *
1660: * @param resourceURL
1661: * @return
1662: */
1663: public static List getVirtualCollectionMemberNames(String sPath) {
1664:
1665: try {
1666: sPath = URLDecoder.decode(sPath, UTF_8);
1667: } catch (UnsupportedEncodingException e) {
1668: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1669: }
1670:
1671: DAVCollectionDesc desc = getCollectionDesc(sPath);
1672:
1673: List members = new ArrayList();
1674:
1675: if (desc != null) {
1676: List fullpaths = desc.getMembers();
1677:
1678: if (fullpaths != null) {
1679: for (Iterator iter = fullpaths.iterator(); iter
1680: .hasNext();) {
1681: String sMemberPath = (String) iter.next();
1682: members.add(getLastSegment(sMemberPath));
1683: }
1684: }
1685: }
1686:
1687: return members;
1688: }
1689:
1690: /**
1691: * Returns a <code>String</code> stripped of anything after and including a '.',
1692: * if there is one.
1693: *
1694: *
1695: * @param sName
1696: * @return
1697: */
1698: public static String stripExtension(String sName) {
1699: int nDotIndex = sName.indexOf(".");
1700: if (nDotIndex > 0) {
1701: sName = sName.substring(0, nDotIndex);
1702: }
1703:
1704: return sName;
1705: }
1706:
1707: /**
1708: * Returns the resource type for a given class name.
1709: *
1710: * @param sClassName
1711: * @return
1712: */
1713: public static String getResourceTypeFromClass(String sClassName)
1714: throws NameResolverException {
1715: String sResult = RESOURCE_TYPE_RESOURCE;
1716:
1717: Class clss = null;
1718: try {
1719: clss = Class.forName(sClassName);
1720: } catch (ClassNotFoundException e) {
1721: throw new NameResolverException(e.getLocalizedMessage(), e);
1722: }
1723:
1724: if (Profile.class.isAssignableFrom(clss) == true) {
1725: sResult = "property";
1726: } else if (AbstractParentObject.class.isAssignableFrom(clss) == true) {
1727: sResult = RESOURCE_TYPE_COLLECTION;
1728: } else if (CLASS_2_RESOURCE_TYPE_MAPPING
1729: .containsKey(sClassName)) {
1730: sResult = (String) CLASS_2_RESOURCE_TYPE_MAPPING
1731: .get(sClassName);
1732: }
1733:
1734: return sResult;
1735: }
1736:
1737: /**
1738: * Returns the Harmonise classname appropriate for the given combination of
1739: * resource type and content type.
1740: *
1741: * @param sResourceType
1742: * @param sContentType
1743: * @return
1744: */
1745: public static String getClassFromResourceTypeDesc(
1746: String sResourceType, String sContentType) {
1747: String sClassName = null;
1748: if (sContentType != null && sContentType.length() > 0) {
1749: if (sContentType.startsWith("text") == true) {
1750: sClassName = Document.class.getName();
1751: } else {
1752: sClassName = Asset.class.getName();
1753: }
1754: } else {
1755: Iterator iter = CLASS_2_RESOURCE_TYPE_MAPPING.keySet()
1756: .iterator();
1757: boolean bFound = false;
1758: while (iter.hasNext() && bFound == false) {
1759: String sTmpName = (String) iter.next();
1760:
1761: if (CLASS_2_RESOURCE_TYPE_MAPPING.get(sTmpName).equals(
1762: sResourceType) == true) {
1763: sClassName = sTmpName;
1764: bFound = true;
1765: }
1766: }
1767: }
1768:
1769: return sClassName;
1770: }
1771:
1772: /**
1773: * @param sDomainObj
1774: */
1775: public static String getRootForClass(String sClassname)
1776: throws NameResolverException {
1777:
1778: StringBuffer sResult = new StringBuffer();
1779:
1780: sResult.append(URL_SEPARATOR).append(WEBDAV_ROOT_MARKER)
1781: .append(URL_SEPARATOR);
1782:
1783: try {
1784: AbstractChildObject child = (AbstractChildObject) Class
1785: .forName(sClassname).newInstance();
1786:
1787: String sParentClass = child.getParentObjectClassName();
1788:
1789: boolean bFound = false;
1790:
1791: Iterator iter = ROOT_COLLECTION_DESCS.values().iterator();
1792:
1793: while (iter.hasNext() && bFound == false) {
1794: DAVCollectionDesc desc = (DAVCollectionDesc) iter
1795: .next();
1796:
1797: if (desc.getHarmoniseClass().equals(sParentClass) == true) {
1798: sResult.append(desc.getURI()).append(URL_SEPARATOR);
1799: bFound = true;
1800: }
1801: }
1802: } catch (InstantiationException e) {
1803: throw new NameResolverException(e.getLocalizedMessage(), e);
1804: } catch (IllegalAccessException e) {
1805: throw new NameResolverException(e.getLocalizedMessage(), e);
1806: } catch (ClassNotFoundException e) {
1807: throw new NameResolverException(e.getLocalizedMessage(), e);
1808: }
1809:
1810: return sResult.toString();
1811: }
1812:
1813: /**
1814: * Retutrns the collection description for given path if it is stored in
1815: * <code>ROOT_COLLECTION_DESCS</code>.
1816: *
1817: * @param sPath
1818: * @return
1819: */
1820: private static DAVCollectionDesc getCollectionDesc(String sPath) {
1821: DAVCollectionDesc desc = null;
1822:
1823: String sSubPath = sPath.substring(sPath
1824: .indexOf(WEBDAV_ROOT_MARKER)
1825: + WEBDAV_ROOT_MARKER.length() + 1);
1826:
1827: if (sSubPath.endsWith(URL_SEPARATOR)) {
1828: sSubPath = sSubPath.substring(0, sSubPath.length() - 1);
1829: }
1830:
1831: desc = (DAVCollectionDesc) ROOT_COLLECTION_DESCS.get(sSubPath);
1832:
1833: return desc;
1834: }
1835:
1836: /**
1837: * @param resourceURL
1838: * @return
1839: */
1840: public static boolean isArchivedVirtualCollection(URL resourceURL) {
1841: boolean bIsArchVirt = false;
1842: String sPath = resourceURL.getPath();
1843:
1844: if (isArchiveURL(sPath) == true) {
1845: sPath = sPath
1846: .replaceFirst(URL_SEPARATOR + ARCHIVE_NAME, "");
1847:
1848: bIsArchVirt = isVirtualCollection(sPath);
1849: }
1850:
1851: return bIsArchVirt;
1852: }
1853:
1854: public static boolean hasValidDAVPath(AbstractChildObject child)
1855: throws WebDAVException {
1856: boolean bHasValidDAVpath = false;
1857:
1858: if (child != null) {
1859: try {
1860: String sOHPath = child.getPath();
1861: if (sOHPath != null) {
1862: String sClassname = child
1863: .getParentObjectClassName();
1864: Iterator iter = ROOT_COLLECTION_DESCS.values()
1865: .iterator();
1866:
1867: while (iter.hasNext() && bHasValidDAVpath == false) {
1868: DAVCollectionDesc desc = (DAVCollectionDesc) iter
1869: .next();
1870:
1871: if (desc.isVirtual() == false
1872: && desc.getHarmoniseClass().equals(
1873: sClassname)
1874: && sOHPath.startsWith(desc
1875: .getHarmonisePath())) {
1876: bHasValidDAVpath = true;
1877: }
1878: }
1879: }
1880:
1881: } catch (DataAccessException e) {
1882: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
1883: throw new WebDAVException(
1884: WebDAVStatus.SC_INTERNAL_SERVER_ERROR, e
1885: .getLocalizedMessage());
1886: }
1887:
1888: }
1889:
1890: return bHasValidDAVpath;
1891: }
1892:
1893: /**
1894: * Returns child from list which matches the key given.
1895: *
1896: * @param children
1897: * @param nKey
1898: * @return
1899: * @throws DataAccessException
1900: */
1901: private static AbstractChildObject getChildByKeyFromList(
1902: List children, int nKey) throws DataAccessException {
1903: AbstractChildObject child = null;
1904: Iterator iter = children.iterator();
1905:
1906: while (iter.hasNext() && child == null) {
1907: AbstractChildObject tmpChild = (AbstractChildObject) iter
1908: .next();
1909:
1910: if (tmpChild.getKey() == nKey) {
1911: child = tmpChild;
1912: }
1913:
1914: }
1915:
1916: return child;
1917: }
1918:
1919: /**
1920: * Returns the correct namespace for the given property.
1921: *
1922: * @param prop
1923: * @return
1924: */
1925: public static NamespaceType getPropertyNamespace(Property prop)
1926: throws DataAccessException {
1927: NamespaceType ns = null;
1928:
1929: List rbs_props = AuthorizationValidator
1930: .getSecurityProperties(prop.getDataStoreInterface());
1931:
1932: if (rbs_props.contains(prop)) {
1933: ns = NamespaceType.OHRM_RBS;
1934: } else if (prop instanceof WorkflowProperty) {
1935: ns = NamespaceType.OHRM_WORKFLOW;
1936: } else {
1937: ns = NamespaceType.OHRM;
1938: }
1939:
1940: return ns;
1941: }
1942:
1943: /**
1944: * Returns the correct profile for the <code>AbstarctProfiledObject</code>
1945: * for the given namespace URI. If the object doesn not have an associated
1946: * profile for a recognised namespace the profile is created, attached to
1947: * the object and returned.
1948: *
1949: * @param profObj
1950: * @param sURI
1951: * @return
1952: * @throws DataAccessException
1953: * @throws InvalidProfileException
1954: */
1955: public static Profile getProfileForNamespaceURI(
1956: AbstractProfiledObject profObj, String sURI)
1957: throws DataAccessException, InvalidProfileException {
1958: Profile nsProf = null;
1959: AbstractDataStoreInterface dsi = profObj
1960: .getDataStoreInterface();
1961: if (sURI.equals(NamespaceType.OHRM_RBS.getURI()) == true) {
1962:
1963: nsProf = profObj
1964: .getProfile(AuthorityProfile.SECURITY_PROFILE_NAME);
1965: if (nsProf == null) {
1966: nsProf = new AuthorityProfile(dsi);
1967: profObj.addProfile(nsProf);
1968: }
1969:
1970: } else if (sURI.equals(NamespaceType.OHRM.getURI()) == true) {
1971: nsProf = profObj.getProfile();
1972: if (nsProf == null) {
1973: nsProf = new Profile(dsi);
1974: profObj.setProfile(nsProf);
1975: }
1976: } else if (sURI.equals(NamespaceType.OHRM_WORKFLOW.getURI()) == true) {
1977: nsProf = profObj
1978: .getProfile(WorkflowProfile.WORKFLOW_PROFILE_NAME);
1979: if (nsProf == null) {
1980: nsProf = new WorkflowProfile(dsi);
1981: profObj.addProfile(nsProf);
1982: }
1983: }
1984:
1985: return nsProf;
1986: }
1987:
1988: /**
1989: * Returns <code>true</code> if the specified path starts
1990: * with the <code>WEBDAV_ROOT_MARKER</code> segment.
1991: *
1992: * @param path
1993: * @return
1994: */
1995: public static boolean isDAVPath(String sPath) {
1996: boolean bIsDAVPath = false;
1997:
1998: if (sPath != null) {
1999: bIsDAVPath = sPath.startsWith(URL_SEPARATOR
2000: + WEBDAV_ROOT_MARKER);
2001: }
2002:
2003: return bIsDAVPath;
2004: }
2005:
2006: }
|