/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.content.contenttype; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import org.apache.commons.lang.StringUtils; import org.jdom.Attribute; import org.jdom.Element; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; import com.enonic.cms.core.content.contenttype.dataentryconfig.BinaryDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.CheckboxDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.DataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.DataEntryConfigType; import com.enonic.cms.core.content.contenttype.dataentryconfig.DateDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.DropdownDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.FileDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.FilesDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.HtmlAreaDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.ImageDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.ImagesDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.KeywordsDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.MultipleChoiceDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.RadioButtonDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.RelatedContentDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.TextAreaDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.TextDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.UrlDataEntryConfig; import com.enonic.cms.core.content.contenttype.dataentryconfig.XmlDataEntryConfig; /** * Jun 7, 2009 */ public class InputConfigParser { private int inputConfigPosition; private String inputName; public InputConfigParser( int inputConfigPosition ) { this.inputConfigPosition = inputConfigPosition; } public DataEntryConfig parserInputConfigElement( Element inputEl ) { inputName = parseInputName( inputEl ); DataEntryConfigType type = parseType( inputEl ); if ( type == DataEntryConfigType.HTMLAREA ) { return parseHtmlAreaInputConfig( inputEl ); } else if ( type == DataEntryConfigType.TEXT ) { return parseTextInputConfig( inputEl ); } else if ( type == DataEntryConfigType.XML ) { return parseXmlInputConfig( inputEl ); } else if ( type == DataEntryConfigType.URL ) { return parseUrlInputConfig( inputEl ); } else if ( type == DataEntryConfigType.RELATEDCONTENT ) { return parseRelatedContentInputConfig( inputEl ); } else if ( type == DataEntryConfigType.BINARY ) { return parseBinaryInputConfig( inputEl ); } else if ( type == DataEntryConfigType.CHECKBOX ) { return parseCheckboxInputConfig( inputEl ); } else if ( type == DataEntryConfigType.DATE ) { return parseDateInputConfig( inputEl ); } else if ( type == DataEntryConfigType.DROPDOWN ) { return parseDropdownInputConfig( inputEl ); } else if ( type == DataEntryConfigType.FILE ) { return parseFileInputConfig( inputEl ); } else if ( type == DataEntryConfigType.FILES ) { return parseFilesInputConfig( inputEl ); } else if ( type == DataEntryConfigType.IMAGE ) { return parseImageInputConfig( inputEl ); } else if ( type == DataEntryConfigType.IMAGES ) { return parseImagesInputConfig( inputEl ); } else if ( type == DataEntryConfigType.KEYWORDS ) { return parseKeywordsInputConfig( inputEl ); } else if ( type == DataEntryConfigType.MULTIPLE_CHOICE ) { return parseMultipleChoiceInputConfig( inputEl ); } else if ( type == DataEntryConfigType.RADIOBUTTON ) { return parseRadioButtonInputConfig( inputEl ); } else if ( type == DataEntryConfigType.TEXT_AREA ) { return parseTextAreaInputConfig( inputEl ); } else { throw new InvalidContentTypeConfigException( "Type not supported in input config '" + inputName + "' at position: " + inputConfigPosition ); } } private TextAreaDataEntryConfig parseTextAreaInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); String defaultValue = parseDefaultValue( inputEl ); return new TextAreaDataEntryConfig( inputName, required, displayName, xpath ).setDefaultValue( defaultValue ); } private RadioButtonDataEntryConfig parseRadioButtonInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); LinkedHashMap<String, String> optionValuesWithDescription = parseOptions( inputEl ); String defaultValue = parseDefaultValue( inputEl ); return new RadioButtonDataEntryConfig( inputName, required, displayName, xpath, optionValuesWithDescription ).setDefaultValue( defaultValue ); } private MultipleChoiceDataEntryConfig parseMultipleChoiceInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new MultipleChoiceDataEntryConfig( inputName, required, displayName, xpath ); } private KeywordsDataEntryConfig parseKeywordsInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new KeywordsDataEntryConfig( inputName, required, displayName, xpath ); } private BinaryDataEntryConfig parseBinaryInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new BinaryDataEntryConfig( inputName, required, displayName, xpath ); } private ImagesDataEntryConfig parseImagesInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new ImagesDataEntryConfig( inputName, required, displayName, xpath ); } private ImageDataEntryConfig parseImageInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new ImageDataEntryConfig( inputName, required, displayName, xpath ); } private FilesDataEntryConfig parseFilesInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new FilesDataEntryConfig( inputName, required, displayName, xpath ); } private FileDataEntryConfig parseFileInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new FileDataEntryConfig( inputName, required, displayName, xpath ); } private DropdownDataEntryConfig parseDropdownInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); LinkedHashMap<String, String> optionValuesWithDescription = parseOptions( inputEl ); String defaultValue = parseDefaultValue( inputEl ); return new DropdownDataEntryConfig( inputName, required, displayName, xpath, optionValuesWithDescription ).setDefaultValue( defaultValue ); } private DateDataEntryConfig parseDateInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new DateDataEntryConfig( inputName, required, displayName, xpath ); } private CheckboxDataEntryConfig parseCheckboxInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); return new CheckboxDataEntryConfig( inputName, required, displayName, xpath ); } private XmlDataEntryConfig parseXmlInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); String defaultValue = parseDefaultValueAsXML( inputEl ); return new XmlDataEntryConfig( inputName, required, displayName, xpath ).setDefaultValue( defaultValue ); } private RelatedContentDataEntryConfig parseRelatedContentInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); boolean multiple = true; // multiple is true by default String multipleStr = inputEl.getAttributeValue( "multiple" ); if ( multipleStr != null ) { multiple = Boolean.parseBoolean( multipleStr ); } @SuppressWarnings("unchecked") List<Element> contentTypeElements = inputEl.getChildren( "contenttype" ); List<String> contentTypeNames = new ArrayList<String>(); if ( contentTypeElements != null && !contentTypeElements.isEmpty() ) { for ( Element contentTypeElement : contentTypeElements ) { Attribute nameAttr = contentTypeElement.getAttribute( "name" ); if ( nameAttr == null ) { throw new InvalidContentTypeConfigException( "Missing name attribute for contenttype element in input config '" + inputName + "' in position: " + inputConfigPosition ); } String contentTypeName = nameAttr.getValue(); if ( StringUtils.isBlank( contentTypeName ) ) { throw new InvalidContentTypeConfigException( "Missing content type name ('" + contentTypeName + "') in name attribute for contenttype element in input config '" + inputName + "' in position: " + inputConfigPosition ); } contentTypeNames.add( contentTypeName ); } } return new RelatedContentDataEntryConfig( inputName, required, displayName, xpath, multiple, contentTypeNames ); } private TextDataEntryConfig parseTextInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); Integer maxLength = null; Element maxlengthEl = inputEl.getChild( "maxlength" ); if ( maxlengthEl != null ) { String strValue = maxlengthEl.getAttributeValue( "value" ); if ( strValue != null ) { maxLength = new Integer( strValue ); } } String defaultValue = parseDefaultValue( inputEl ); Element regExpEl = inputEl.getChild( "regexp" ); String regExp = null; if ( regExpEl != null ) { regExp = regExpEl.getText(); } return new TextDataEntryConfig( inputName, required, displayName, xpath ).setMaxLength( maxLength ).setDefaultValue( defaultValue ).setRegExp( regExp ); } private UrlDataEntryConfig parseUrlInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); Integer maxLength = null; Element maxlengthEl = inputEl.getChild( "maxlength" ); if ( maxlengthEl != null ) { String strValue = maxlengthEl.getAttributeValue( "value" ); if ( strValue != null ) { maxLength = new Integer( strValue ); } } String defaultValue = parseDefaultValue( inputEl ); return new UrlDataEntryConfig( inputName, required, displayName, xpath, maxLength ).setDefaultValue( defaultValue ); } private HtmlAreaDataEntryConfig parseHtmlAreaInputConfig( Element inputEl ) { boolean required = parseInputRequired( inputEl ); String displayName = parseInputDisplayName( inputEl ); String xpath = parseInputXpath( inputEl ); String defaultValue = parseDefaultValueAsXML( inputEl ); return new HtmlAreaDataEntryConfig( inputName, required, displayName, xpath ).setDefaultValue( defaultValue ); } private String parseInputName( Element inputEl ) { String nameAttribute = inputEl.getAttributeValue( "name" ); if ( nameAttribute == null || nameAttribute.trim().equals( "" ) ) { throw new InvalidContentTypeConfigException( "Missing name attribute in input config position: " + inputConfigPosition ); } return nameAttribute; } private DataEntryConfigType parseType( Element inputEl ) { Attribute typeAttr = inputEl.getAttribute( "type" ); if ( typeAttr == null ) { throw new InvalidContentTypeConfigException( "Missing type attribute in input config position: " + inputConfigPosition ); } String typeName = typeAttr.getValue(); if ( typeName == null ) { throw new InvalidContentTypeConfigException( "Missing value in type attribute in input config position: " + inputConfigPosition ); } DataEntryConfigType type = DataEntryConfigType.parse( typeName ); if ( type == null ) { throw new InvalidContentTypeConfigException( "Unknown type '" + typeName + "' in input config position: " + inputConfigPosition ); } return type; } private String parseInputDisplayName( Element inputEl ) { Element displayElement = inputEl.getChild( "display" ); if ( displayElement != null ) { return displayElement.getText(); } else { throw new InvalidContentTypeConfigException( "Missing display element for input config '" + inputName + "' in position: " + inputConfigPosition ); } } private String parseDefaultValue( Element inputEl ) { Element displayElement = inputEl.getChild( "default" ); if ( displayElement != null ) { return displayElement.getText(); } return null; } private String parseDefaultValueAsXML( Element inputEl ) { final Element aDefault = inputEl.getChild( "default" ); if ( aDefault == null ) { return null; } final List children = aDefault.getChildren(); if ( !children.isEmpty() ) { final Element displayElement = (Element) children.get( 0 ); if ( displayElement != null ) { final XMLOutputter outputter = new XMLOutputter( Format.getPrettyFormat() ); return outputter.outputString( displayElement ); } } return null; } private String parseInputXpath( Element inputEl ) { Element xPathElement = inputEl.getChild( "xpath" ); if ( xPathElement != null ) { return xPathElement.getText(); } else { throw new InvalidContentTypeConfigException( "Missing xpath element for input config '" + inputName + "' in position: " + inputConfigPosition ); } } private LinkedHashMap<String, String> parseOptions( Element inputEl ) { LinkedHashMap<String, String> options = new LinkedHashMap<String, String>(); Element optionsElement = inputEl.getChild( "options" ); if ( optionsElement != null ) { List children = optionsElement.getChildren( "option" ); for ( Object child : children ) { Element option = (Element) child; Attribute valueAttribute = option.getAttribute( "value" ); if ( valueAttribute != null ) { String value = valueAttribute.getValue(); String description = option.getText(); options.put( value, description ); } } } return options; } private boolean parseInputRequired( Element inputEl ) { return Boolean.valueOf( inputEl.getAttributeValue( "required", "false" ) ); } }