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

com.day.cq.wcm.foundation.ImageMap Maven / Gradle / Ivy

/*
 * Copyright 1997-2008 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */
package com.day.cq.wcm.foundation;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class is used for parsing image map definitions as generated by the
 * CqImageMap component and make them available through an API to
 * CQ components.
 * 

* The class is designed for single-threaded use. */ public class ImageMap { /** * Inner class that represents an area of the map. */ public class ImageArea { /** * type of the area (as required by the area tag) */ private final String type; /** * coordinates of the area (as required by the area tag) */ private final String coordinates; /** * HREF of the area (null if none is specified) */ private final String href; /** * alternative text of the area (unicoded; null if none is specified) */ private final String altText; /** * target of the area's HREF (null if none is specified) */ private final String target; /** * Creates a new ImageArea with the given parameters. * * @param type type/shape of the image area * @param coordinates coordinates * @param href HREF (optional) * @param altText alternative text (optional) * @param target target (frame/window; optional) */ protected ImageArea(String type, String coordinates, String href, String altText, String target) { log.debug("Creating image area; destination: {}; altText: {}; target: {}", new Object[] { href, altText, target }); this.type = type; this.coordinates = coordinates; this.href = href; this.altText = altText; this.target = target; } /** * Gets the type (= shape attribute) of the image area. * * @return type of the image area */ public String getType() { return type; } /** * Gets the coordinates (= coords attribute) of the image area. * * @return coordinates of the image area */ public String getCoordinates() { return coordinates; } /** * Gets the (optional) HREF of the image area. * * @return HREF of the image area; null if undefined */ public String getHref() { return href; } /** * Gets the alternative text of the image area in unicode format. * * @return alternative text of the image area; null if undefined */ public String getAltText() { return altText; } /** * Gets the target frame/window of the image area. * * @return target frame/window of the image area; null if undefined */ public String getTarget() { return target; } } /** * internal logger */ private static final Logger log = LoggerFactory.getLogger(ImageMap.class); /** * areas of the map */ private final List areas; /** * Creates a new ImageMap object from the given string representation. * * @param mapDefinition string representation (as created by the * CqImageMap component) * @return a suitable representation of the component * @throws IllegalArgumentException if the given string representation is invalid */ public static ImageMap fromString(String mapDefinition) throws IllegalArgumentException { ImageMap theMap = new ImageMap(); theMap.createFromString(mapDefinition); return theMap; } /** * Private constructor. */ private ImageMap() { this.areas = new ArrayList(10); } /** * Decodes a string (encoded with encodeString() that is contained in another * string. The (partial) string to parse has to be enclosed in quotation marks. *

* For example:
* decodeFromContainingString("x:\"abc\\"\"", 2) will return * { "decoded": "abc"", "nextPos": 9 } * * @param containingString the containing string * @param parseStartPos position where parsing should start * @return decoding result; Object[] with the decoded string as first * element (type String); the first character position after the * closing quotation as second element (type Integer) * @throws IllegalArgumentException if the string has an invalid format */ private Object[] decodeFromContainingString(String containingString, int parseStartPos) { int quotPos = containingString.indexOf("\"", parseStartPos); if (quotPos < 0) { throw new IllegalArgumentException( "No opening quotation mark found in string."); } boolean isDone = false; int currentCharPos = quotPos + 1; StringBuilder text = new StringBuilder(128); boolean isEscaped = false; while (!isDone) { char charToProcess = containingString.charAt(currentCharPos); if ((charToProcess == '\"') && (!isEscaped)) { isDone = true; } else if (charToProcess == '\\') { if (isEscaped) { text.append("\\"); isEscaped = false; } else { isEscaped = true; } } else if (isEscaped) { text.append(charToProcess); isEscaped = false; } else { text.append(charToProcess); } currentCharPos++; if ((currentCharPos >= containingString.length()) && (!isDone)) { throw new IllegalArgumentException( "No final quotation mark found in string."); } } return new Object[] { text.toString(), currentCharPos }; } /** * Parses the destination from the given image map string (full version). * * @param value image map definition (full version) * @param parseStartPos start position (in version) where the destination * has to be parsed from * @return array with url as first element, target as second, text as third (all of them * of type String and the position of the next character to parse * as fourth element (Integer * @throws IllegalArgumentException if the string definition has a non-parseable format */ private Object[] parseAreaDestination(String value, int parseStartPos) throws IllegalArgumentException { int parsePos = parseStartPos; Object[] parseResult; char charToCheck; String url = null; if (parsePos < value.length()) { charToCheck = value.charAt(parsePos); if (charToCheck != '|') { parseResult = this.decodeFromContainingString(value, parsePos); url = (String) parseResult[0]; parsePos = (Integer) parseResult[1]; } parsePos++; } String target = null; if (parsePos < value.length()) { charToCheck = value.charAt(parsePos); if (charToCheck != '|') { parseResult = this.decodeFromContainingString(value, parsePos); target = (String) parseResult[0]; parsePos = (Integer) parseResult[1]; } parsePos++; } String text = null; if (parsePos < value.length()) { charToCheck = value.charAt(parsePos); if (charToCheck != ']') { parseResult = this.decodeFromContainingString(value, parsePos); if (parseResult == null) { return null; } else { text = (String) parseResult[0]; parsePos = (Integer) parseResult[1]; } } } return new Object[] { url, target, text, parsePos + 1 }; } /** * Creates a new ImageMap object from the given string representation. * * @param strDefinition string representation (as created by the * CqImageMap component) * @throws IllegalArgumentException if the given string representation is invalid */ private void createFromString(String strDefinition) throws IllegalArgumentException { this.areas.clear(); int processingPos = 0; while (processingPos < strDefinition.length()) { int startPos = strDefinition.indexOf("[", processingPos); if (startPos < 0) { break; } int coordEndPos = strDefinition.indexOf(")", startPos + 1); if (coordEndPos < 0) { break; } String areaDef = strDefinition.substring(startPos + 1, coordEndPos + 1); int contentStartPos = areaDef.indexOf("("); if (contentStartPos < 0) { throw new IllegalArgumentException("Could not create image map; area " + "definition is not in format 'type(coords)...'."); } String type = areaDef.substring(0, contentStartPos); String coords = areaDef.substring(contentStartPos + 1, areaDef.length() - 1); Object[] areaDestination = this.parseAreaDestination(strDefinition, coordEndPos + 1); processingPos = (Integer) areaDestination[3]; String url = (String) areaDestination[0]; String target = (String) areaDestination[1]; String text = (String) areaDestination[2]; this.areas.add(new ImageArea(type, coords, url, text, target)); } } /** * Returns the HTML code required for the image map. *

* Parameters originalSize and scaled can be used to create * a scaled map that is suitable for a scaled image. * * @param id id of the image map * @return HTML code representing the image map */ public String draw(String id) { StringBuilder htmlCode = new StringBuilder(128); htmlCode.append(""); for (ImageArea areaToDraw : this.areas) { htmlCode.append("\"")"); } htmlCode.append(""); log.debug("Image map HTML code: {}", htmlCode); return htmlCode.toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy