All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.file.wrapper.CmsResourceWrapperUtils Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software GmbH & Co. KG, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.file.wrapper;

import org.opencms.file.CmsFile;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProperty;
import org.opencms.file.CmsPropertyDefinition;
import org.opencms.file.CmsResource;
import org.opencms.file.types.CmsResourceTypePlain;
import org.opencms.file.types.I_CmsResourceType;
import org.opencms.i18n.CmsEncoder;
import org.opencms.main.CmsException;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsStringUtil;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Helper class with several methods used by different implementations of the
 * interface {@link I_CmsResourceWrapper}.

* * It provides methods to add or remove file extensions to resources, to handle * creating and writing property files and to add the byte order mask to UTF-8 * byte contents.

* * @since 6.2.4 */ public final class CmsResourceWrapperUtils { /** The extension to use for the property file. */ public static final String EXTENSION_PROPERTIES = "properties"; /** Property name used for reading / changing the resource type. */ public static final String PROPERTY_RESOURCE_TYPE = "resourceType"; /** The prefix used for a shared property entry. */ public static final String SUFFIX_PROP_INDIVIDUAL = ".i"; /** The prefix used for a shared property entry. */ public static final String SUFFIX_PROP_SHARED = ".s"; /** The UTF-8 bytes to add to the beginning of text contents. */ public static final byte[] UTF8_MARKER = new byte[] {(byte)0xEF, (byte)0xBB, (byte)0xBF}; /** Pattern to use for incoming strings before storing in OpenCms. */ private static final Pattern PATTERN_UNESCAPE = Pattern.compile("\\\\([^ntru\n\r])"); /** * Hide utility class constructor.

*/ private CmsResourceWrapperUtils() { // noop } /** * Adds a file extension to the resource name.

* * If the file with the new extension already exists, an index count will be * added before the final extension.

* * For example: index.html.1.jsp.

* * @see #removeFileExtension(CmsObject, String, String) * * @param cms the actual CmsObject * @param resourcename the name of the resource where to add the file extension * @param extension the extension to add * * @return the resource name with the added file extension */ public static String addFileExtension(CmsObject cms, String resourcename, String extension) { if (!extension.startsWith(".")) { extension = "." + extension; } if (!resourcename.endsWith(extension)) { String name = resourcename + extension; int count = 0; while (cms.existsResource(name)) { count++; name = resourcename + "." + count + extension; } return name; } return resourcename; } /** * Adds the UTF-8 marker add the beginning of the byte array.

* * @param content the byte array where to add the UTF-8 marker * * @return the byte with the added UTF-8 marker at the beginning */ public static byte[] addUtf8Marker(byte[] content) { if ((content != null) && (content.length >= 3) && (content[0] == UTF8_MARKER[0]) && (content[1] == UTF8_MARKER[1]) && (content[2] == UTF8_MARKER[2])) { return content; } if (content == null) { content = new byte[0]; } byte[] ret = new byte[UTF8_MARKER.length + content.length]; System.arraycopy(UTF8_MARKER, 0, ret, 0, UTF8_MARKER.length); System.arraycopy(content, 0, ret, UTF8_MARKER.length, content.length); return ret; } /** * Creates a virtual CmsFile with the individual and shared properties as content.

* * For example looks like this:
* Title.i=The title of the resource set as individual property
* Title.s=The title of the resource set as shared property
* * @see #writePropertyFile(CmsObject, String, byte[]) * * @param cms the initialized CmsObject * @param res the resource where to read the properties from * @param path the full path to set for the created property file * * @return the created CmsFile with the individual and shared properties as the content * * @throws CmsException if something goes wrong */ public static CmsFile createPropertyFile(CmsObject cms, CmsResource res, String path) throws CmsException { StringBuffer content = new StringBuffer(); // header content.append("# Properties for resource "); content.append(res.getRootPath()); content.append("\n"); content.append("#\n"); content.append("# ${property_name}.i : individual property\n"); content.append("# ${property_name}.s : shared property\n\n"); List propertyDef = cms.readAllPropertyDefinitions(); Map activeProperties = CmsProperty.getPropertyMap(cms.readPropertyObjects(res, false)); String resourceType = OpenCms.getResourceManager().getResourceType(res).getTypeName(); content.append("resourceType="); content.append(resourceType); content.append("\n\n"); // iterate over all possible properties for the resource Iterator i = propertyDef.iterator(); while (i.hasNext()) { CmsPropertyDefinition currentPropertyDef = i.next(); String propName = currentPropertyDef.getName(); CmsProperty currentProperty = activeProperties.get(propName); if (currentProperty == null) { currentProperty = new CmsProperty(); } String individualValue = currentProperty.getStructureValue(); String sharedValue = currentProperty.getResourceValue(); if (individualValue == null) { individualValue = ""; } if (sharedValue == null) { sharedValue = ""; } individualValue = escapeString(individualValue); sharedValue = escapeString(sharedValue); content.append(propName); content.append(SUFFIX_PROP_INDIVIDUAL); content.append("="); content.append(individualValue); content.append("\n"); content.append(propName); content.append(SUFFIX_PROP_SHARED); content.append("="); content.append(sharedValue); content.append("\n\n"); } CmsWrappedResource wrap = new CmsWrappedResource(res); wrap.setRootPath(addFileExtension(cms, path, EXTENSION_PROPERTIES)); int plainId = OpenCms.getResourceManager().getResourceType( CmsResourceTypePlain.getStaticTypeName()).getTypeId(); wrap.setTypeId(plainId); wrap.setFolder(false); CmsFile ret = wrap.getFile(); try { ret.setContents(content.toString().getBytes(CmsEncoder.ENCODING_UTF_8)); } catch (UnsupportedEncodingException e) { // this will never happen since UTF-8 is always supported ret.setContents(content.toString().getBytes()); } return ret; } /** * Removes an added file extension from the resource name.

* *

    *
  • If there is only one extension, nothing will be removed.
  • *
  • If there are two extensions, the last one will be removed.
  • *
  • If there are more than two extensions the last one will be removed and * if then the last extension is a number, the extension with the number * will be removed too.
  • *
* * @see #addFileExtension(CmsObject, String, String) * * @param cms the initialized CmsObject * @param resourcename the resource name to remove the file extension from * @param extension the extension to remove * * @return the resource name without the removed file extension */ public static String removeFileExtension(CmsObject cms, String resourcename, String extension) { if (resourcename.equals("")) { resourcename = "/"; } // get the filename without the path String name = CmsResource.getName(resourcename); String[] tokens = name.split("\\."); String suffix = null; // check if there is more than one extension if (tokens.length > 2) { // check if last extension is "jsp" if (extension.equalsIgnoreCase(tokens[tokens.length - 1])) { suffix = "." + extension; // check if there is another extension with a numeric index if (tokens.length > 3) { try { int index = Integer.valueOf(tokens[tokens.length - 2]).intValue(); suffix = "." + index + suffix; } catch (NumberFormatException ex) { // noop } } } } else if (tokens.length == 2) { // there is only one extension!! // only remove the last extension, if the resource without the extension exists // and the extension fits if ((cms.existsResource(CmsResource.getFolderPath(resourcename) + tokens[0])) && (extension.equals(tokens[1]))) { suffix = "." + tokens[1]; } } if (suffix != null) { String path = resourcename.substring(0, resourcename.length() - suffix.length()); return path; } return resourcename; } /** * Removes the UTF-8 marker from the beginning of the byte array.

* * @param content the byte array where to remove the UTF-8 marker * * @return the byte with the removed UTF-8 marker at the beginning */ public static byte[] removeUtf8Marker(byte[] content) { if ((content != null) && (content.length >= 3) && (content[0] == UTF8_MARKER[0]) && (content[1] == UTF8_MARKER[1]) && (content[2] == UTF8_MARKER[2])) { byte[] ret = new byte[content.length - UTF8_MARKER.length]; System.arraycopy(content, 3, ret, 0, content.length - UTF8_MARKER.length); return ret; } return content; } /** * Takes the content which should be formatted as a property file and set them * as properties to the resource.

* * @see #createPropertyFile(CmsObject, CmsResource, String) * * @param cms the initialized CmsObject * @param resourcename the name of the resource where to set the properties * @param content the properties to set (formatted as a property file) * * @throws CmsException if something goes wrong */ public static void writePropertyFile(CmsObject cms, String resourcename, byte[] content) throws CmsException { Properties properties = new Properties(); try { String props = CmsEncoder.createString(content, CmsEncoder.ENCODING_UTF_8); props = unescapeString(props); props = CmsEncoder.encodeJavaEntities(props, CmsEncoder.ENCODING_ISO_8859_1); byte[] modContent = props.getBytes(CmsEncoder.ENCODING_ISO_8859_1); properties.load(new ByteArrayInputStream(modContent)); List propList = new ArrayList(); Iterator> it = properties.entrySet().iterator(); while (it.hasNext()) { Map.Entry e = it.next(); String key = (String)e.getKey(); String value = (String)e.getValue(); if (key.endsWith(SUFFIX_PROP_SHARED)) { propList.add( new CmsProperty(key.substring(0, key.length() - SUFFIX_PROP_SHARED.length()), null, value)); } else if (key.endsWith(SUFFIX_PROP_INDIVIDUAL)) { propList.add( new CmsProperty(key.substring(0, key.length() - SUFFIX_PROP_INDIVIDUAL.length()), value, null)); } } cms.writePropertyObjects(resourcename, propList); String newType = properties.getProperty(PROPERTY_RESOURCE_TYPE); if (newType != null) { newType = newType.trim(); if (OpenCms.getResourceManager().hasResourceType(newType)) { I_CmsResourceType newTypeObj = OpenCms.getResourceManager().getResourceType(newType); cms.chtype(resourcename, newTypeObj.getTypeId()); } } } catch (IOException e) { // noop } } /** * Escapes the value of a property in OpenCms to be displayed * correctly in a property file.

* * Mainly handles all escaping sequences that start with a backslash.

* * @see #unescapeString(String) * * @param value the value with the string to be escaped * * @return the escaped string */ private static String escapeString(String value) { Map substitutions = new HashMap(); substitutions.put("\n", "\\n"); substitutions.put("\t", "\\t"); substitutions.put("\r", "\\r"); return CmsStringUtil.substitute(value, substitutions); } /** * Unescapes the value of a property in a property file to * be saved correctly in OpenCms.

* * Mainly handles all escaping sequences that start with a backslash.

* * @see #escapeString(String) * * @param value the value taken form the property file * * @return the unescaped string value */ private static String unescapeString(String value) { Matcher matcher = PATTERN_UNESCAPE.matcher(value); return matcher.replaceAll("\\\\\\\\$1"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy