/* ===============================================================================
*
* Part of the InfoGlue Content Management Platform (www.infoglue.org)
*
* ===============================================================================
*
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2, as published by the
* Free Software Foundation. See the file LICENSE.html for more information.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc. / 59 Temple
* Place, Suite 330 / Boston, MA 02111-1307 / USA.
*
* ===============================================================================
*/
package org.infoglue.cms.applications.managementtool.actions;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.xml.transform.TransformerException;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xpath.XPathAPI;
import org.infoglue.cms.applications.common.actions.InfoGlueAbstractAction;
import org.infoglue.cms.controllers.kernel.impl.simple.CategoryController;
import org.infoglue.cms.controllers.kernel.impl.simple.ContentTypeDefinitionController;
import org.infoglue.cms.controllers.kernel.impl.simple.LanguageController;
import org.infoglue.cms.entities.management.CategoryAttribute;
import org.infoglue.cms.entities.management.ContentTypeAttribute;
import org.infoglue.cms.entities.management.ContentTypeDefinitionVO;
import org.infoglue.cms.exception.ConstraintException;
import org.infoglue.cms.exception.SystemException;
import org.infoglue.cms.providers.ContentDetailPageResolver;
import org.infoglue.cms.services.ContentDetailPageResolversService;
import org.infoglue.cms.util.CmsPropertyHandler;
import org.infoglue.cms.util.ConstraintExceptionBuffer;
import org.infoglue.cms.util.XMLHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* This class implements the action class for viewContentTypeDefinition.
* The use-case lets the user see all information about a specific site/contentTypeDefinition.
*
* @author Mattias Bogeblad
*/
public class ViewContentTypeDefinitionAction extends InfoGlueAbstractAction
{
private final static Logger logger = Logger.getLogger(ViewContentTypeDefinitionAction.class.getName());
private static final long serialVersionUID = 1L;
public static final String USE_EDITOR = "useEditor";
private static CategoryController categoryController = CategoryController.getController();
private ContentTypeDefinitionVO contentTypeDefinitionVO;
private String currentContentTypeEditorViewLanguageCode;
private List<ContentTypeAttribute> attributes = null;
private ContentTypeAttribute attribute = null;
private List availableLanguages = null;
private List languageVOList;
private String title;
private String inputTypeId;
private String attributeName;
private String newAttributeName;
private String attributeParameterId;
private String attributeParameterValueId;
private String newAttributeParameterValueId;
private String attributeParameterValueLabel;
private String attributeParameterValueLocale;
private String attributeToExpand;
private String assetKey;
private String newAssetKey;
private String categoryKey;
private String newCategoryKey;
private Boolean isMandatory = new Boolean(false);
private String description = "";
private Integer maximumSize;
private String allowedContentTypes = "any";
private String imageWidth;
private String imageHeight;
private String assetUploadTransformationsSettings = "";
private List activatedName = new ArrayList();
private Integer tabToActivate = -1;
private Integer versionsToKeep = -1;
public ViewContentTypeDefinitionAction()
{
this(new ContentTypeDefinitionVO());
}
public ViewContentTypeDefinitionAction(ContentTypeDefinitionVO contentTypeDefinitionVO)
{
this.contentTypeDefinitionVO = contentTypeDefinitionVO;
}
protected void initialize(Integer contentTypeDefinitionId) throws Exception
{
this.contentTypeDefinitionVO = ContentTypeDefinitionController.getController().getContentTypeDefinitionVOWithId(contentTypeDefinitionId);
//logger.info("Initializing:" + this.contentTypeDefinitionVO.getSchemaValue());
this.contentTypeDefinitionVO = ContentTypeDefinitionController.getController().validateAndUpdateContentType(this.contentTypeDefinitionVO);
this.contentTypeDefinitionVO = ContentTypeDefinitionController.getController().getContentTypeDefinitionVOWithId(contentTypeDefinitionId);
this.attributes = ContentTypeDefinitionController.getController().getContentTypeAttributes(this.contentTypeDefinitionVO, true);
this.availableLanguages = LanguageController.getController().getLanguageVOList();
try
{
this.versionsToKeep = new Integer(CmsPropertyHandler.getServerNodeProperty("contentTypeDefinitionId_" + this.contentTypeDefinitionVO.getId() + "_versionsToKeep", false, "-1", true));
}
catch (Exception e)
{
logger.warn("Could not get number of versions to keep:" + e.getMessage());
}
}
/**
* The main method that fetches the Value-object for this use-case
*/
public String doExecute() throws Exception
{
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
/**
* The method that initializes all for the editor mode
*/
public String doUseEditor() throws Exception
{
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
/**
* The method that initializes all for the simple mode
*/
public String doUseSimple() throws Exception
{
this.initialize(getContentTypeDefinitionId());
return SUCCESS;
}
public String doInsertAttribute() throws Exception
{
this.initialize(getContentTypeDefinitionId());
String newSchemaValue = ContentTypeDefinitionController.getController().insertContentTypeAttribute(this.contentTypeDefinitionVO.getSchemaValue(), this.inputTypeId, this.activatedName);
this.contentTypeDefinitionVO.setSchemaValue(newSchemaValue);
ContentTypeDefinitionController.getController().update(this.contentTypeDefinitionVO);
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doViewAttribute() throws Exception
{
this.initialize(getContentTypeDefinitionId());
if(this.attributeName == null || this.attributeName.equals(""))
throw new Exception("Must supply parameter 'attributeName'");
for(ContentTypeAttribute attribute : this.attributes)
{
if(attribute.getName().equals(this.attributeName))
this.attribute = attribute;
}
return "successViewAttribute";
}
public String doDeleteAttribute() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String attributesXPath = "/xs:schema/xs:complexType/xs:all/xs:element/xs:complexType/xs:all/xs:element[@name='" + this.attributeName + "']";
NodeList anl = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
if(anl != null && anl.getLength() > 0)
{
Element element = (Element)anl.item(0);
element.getParentNode().removeChild(element);
}
String validatorsXPath = "/xs:schema/xs:complexType[@name = 'Validation']/xs:annotation/xs:appinfo/form-validation/formset/form/field[@property = '" + attributeName + "']";
NodeList anl2 = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), validatorsXPath);
for(int i=0; i<anl2.getLength(); i++)
{
Element element = (Element)anl2.item(i);
element.getParentNode().removeChild(element);
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
/**
* This method moves an content type attribute up one step.
*/
public String doMoveAttributeUp() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String attributesXPath = "/xs:schema/xs:complexType/xs:all/xs:element/xs:complexType/xs:all/xs:element";
NodeList anl = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
Element previousElement = null;
for(int i=0; i < anl.getLength(); i++)
{
Element element = (Element)anl.item(i);
if(element.getAttribute("name").equalsIgnoreCase(this.attributeName) && previousElement != null)
{
Element parent = (Element)element.getParentNode();
parent.removeChild(element);
parent.insertBefore(element, previousElement);
}
previousElement = element;
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
/**
* This method moves an content type attribute down one step.
*/
public String doMoveAttributeDown() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String attributesXPath = "/xs:schema/xs:complexType/xs:all/xs:element/xs:complexType/xs:all/xs:element";
NodeList anl = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
Element parent = null;
Element elementToMove = null;
boolean isInserted = false;
int position = 0;
for(int i=0; i < anl.getLength(); i++)
{
Element element = (Element)anl.item(i);
parent = (Element)element.getParentNode();
if(elementToMove != null)
{
if(position == 2)
{
parent.insertBefore(elementToMove, element);
isInserted = true;
break;
}
else
position++;
}
if(element.getAttribute("name").equalsIgnoreCase(this.attributeName))
{
elementToMove = element;
parent.removeChild(elementToMove);
position++;
}
}
if(!isInserted && elementToMove != null)
parent.appendChild(elementToMove);
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
/**
* This method moves an content type assetKey up one step.
*/
public String doMoveAssetKeyUp() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String attributesXPath = "/xs:schema/xs:simpleType[@name = '" + ContentTypeDefinitionController.ASSET_KEYS + "']/xs:restriction/xs:enumeration[@value='" + this.assetKey + "']";
NodeList anl = XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
if(anl != null && anl.getLength() > 0)
{
Element element = (Element)anl.item(0);
Node parentElement = element.getParentNode();
Node previuosSibling = element.getPreviousSibling();
if(previuosSibling != null)
{
parentElement.removeChild(element);
parentElement.insertBefore(element, previuosSibling);
}
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
/**
* This method moves an content type asset key down one step.
*/
public String doMoveAssetKeyDown() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String attributesXPath = "/xs:schema/xs:simpleType[@name = '" + ContentTypeDefinitionController.ASSET_KEYS + "']/xs:restriction/xs:enumeration[@value='" + this.assetKey + "']";
NodeList anl = XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
if(anl != null && anl.getLength() > 0)
{
Element element = (Element)anl.item(0);
Node parentElement = element.getParentNode();
Node nextSibling = element.getNextSibling();
if(nextSibling != null)
{
parentElement.removeChild(nextSibling);
parentElement.insertBefore(nextSibling, element);
}
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doDeleteAttributeParameterValue() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String attributesXPath = "/xs:schema/xs:complexType/xs:all/xs:element/xs:complexType/xs:all/xs:element[@name='" + this.attributeName + "']/xs:annotation/xs:appinfo/params/param[@id='" + this.attributeParameterId +"']/values/value[@id='" + this.attributeParameterValueId + "']";
NodeList anl = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
if(anl != null && anl.getLength() > 0)
{
Element element = (Element)anl.item(0);
element.getParentNode().removeChild(element);
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doInsertAttributeParameterValue() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String attributesXPath = "/xs:schema/xs:complexType/xs:all/xs:element/xs:complexType/xs:all/xs:element[@name='" + this.attributeName + "']/xs:annotation/xs:appinfo/params/param[@id='" + this.attributeParameterId +"']/values";
NodeList anl = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
if(anl != null && anl.getLength() > 0)
{
Element element = (Element)anl.item(0);
Element newValue = document.createElement("value");
newValue.setAttribute("id", getRandomName());
newValue.setAttribute("label", getRandomName());
element.appendChild(newValue);
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
/**
* We validate that ' ', '.', ''', '"' is not used in the attribute name as that will break the javascripts later.
*/
public String doUpdateAttribute() throws Exception
{
ConstraintExceptionBuffer ceb = new ConstraintExceptionBuffer();
if(this.newAttributeName.indexOf(" ") > -1 || this.newAttributeName.indexOf(".") > -1 || this.newAttributeName.indexOf("'") > -1 || this.newAttributeName.indexOf("\"") > -1)
{
ceb.add(new ConstraintException("ContentTypeAttribute.updateAction", "3500"));
}
ceb.throwIfNotEmpty();
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
//Updating the content attribute
String[] extraParameterNames = getRequest().getParameterValues("parameterNames");
if(extraParameterNames != null)
{
for(int i=0; i < extraParameterNames.length; i++)
{
String extraParameterName = extraParameterNames[i];
String value = getRequest().getParameter(extraParameterName);
String extraParametersXPath = "/xs:schema/xs:complexType/xs:all/xs:element/xs:complexType/xs:all/xs:element[@name='" + this.attributeName + "']/xs:annotation/xs:appinfo/params/param[@id='" + extraParameterName +"']/values/value";
NodeList extraParamsNodeList = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), extraParametersXPath);
if(extraParamsNodeList != null && extraParamsNodeList.getLength() > 0)
{
Element element = (Element)extraParamsNodeList.item(0);
if(extraParameterName.equalsIgnoreCase("values") && (this.inputTypeId.equalsIgnoreCase("select") || this.inputTypeId.equalsIgnoreCase("checkbox") || this.inputTypeId.equalsIgnoreCase("radiobutton")))
{
((Element)element.getParentNode().getParentNode()).setAttribute("inputTypeId", "1");
}
else if(extraParameterName.equalsIgnoreCase("Markup") && this.inputTypeId.equalsIgnoreCase("customfield"))
{
((Element)element.getParentNode().getParentNode()).setAttribute("inputTypeId", "2");
}
else
{
((Element)element.getParentNode().getParentNode()).setAttribute("inputTypeId", "0");
}
String inputTypeId = ((Element)element.getParentNode().getParentNode()).getAttribute("inputTypeId");
if(inputTypeId.equals("0") || inputTypeId.equals("2"))
{
if(this.currentContentTypeEditorViewLanguageCode != null && this.currentContentTypeEditorViewLanguageCode.length() > 0)
{
element.setAttribute("label_" + this.currentContentTypeEditorViewLanguageCode, value);
}
else
{
element.setAttribute("label", value);
}
}
}
}
}
//Updating the name and type
String attributeXPath = "/xs:schema/xs:complexType/xs:all/xs:element/xs:complexType/xs:all/xs:element[@name='" + this.attributeName + "']";
NodeList anl = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), attributeXPath);
if(anl != null && anl.getLength() > 0)
{
Element element = (Element)anl.item(0);
element.setAttribute("name", this.newAttributeName);
element.setAttribute("type", this.inputTypeId);
}
try
{
//Updating the validation part
String validationXPath = "//xs:complexType[@name='Validation']/xs:annotation/xs:appinfo/form-validation/formset/form/field[@property='" + this.attributeName + "']";
NodeList fieldNodeList = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), validationXPath);
if(fieldNodeList != null && fieldNodeList.getLength() > 0)
{
Element element = (Element)fieldNodeList.item(0);
element.setAttribute("property", this.newAttributeName);
}
//Updating the dependent part
String validationDependentXPath = "//xs:complexType[@name='Validation']/xs:annotation/xs:appinfo/form-validation/formset/form/field[@depends='requiredif']/var/var-value";
NodeList requiredIfValueNodeList = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), validationDependentXPath);
if(requiredIfValueNodeList != null && requiredIfValueNodeList.getLength() > 0)
{
for(int i=0; i<requiredIfValueNodeList.getLength(); i++)
{
Element element = (Element)requiredIfValueNodeList.item(0);
if(element.getFirstChild() != null && element.getFirstChild().getNodeValue() != null && element.getFirstChild().getNodeValue().equals(this.attributeName))
element.getFirstChild().setNodeValue(this.newAttributeName);
}
}
}
catch(Exception ve)
{
ve.printStackTrace();
}
this.attributeToExpand = this.newAttributeName;
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doUpdateAttributeParameterValue() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String parameterValueXPath = "/xs:schema/xs:complexType/xs:all/xs:element/xs:complexType/xs:all/xs:element[@name='" + this.attributeName + "']/xs:annotation/xs:appinfo/params/param[@id='" + this.attributeParameterId +"']/values/value[@id='" + this.attributeParameterValueId + "']";
NodeList parameterValuesNodeList = org.apache.xpath.XPathAPI.selectNodeList(document.getDocumentElement(), parameterValueXPath);
if(parameterValuesNodeList != null && parameterValuesNodeList.getLength() > 0)
{
Element element = (Element)parameterValuesNodeList.item(0);
element.setAttribute("id", this.newAttributeParameterValueId);
logger.info("currentContentTypeEditorViewLanguageCode:" + currentContentTypeEditorViewLanguageCode);
logger.info("attributeParameterValueLabel:" + attributeParameterValueLabel);
if(this.currentContentTypeEditorViewLanguageCode != null && this.currentContentTypeEditorViewLanguageCode.length() > 0)
element.setAttribute("label_" + this.currentContentTypeEditorViewLanguageCode, this.attributeParameterValueLabel);
else
element.setAttribute("label", this.attributeParameterValueLabel);
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doInsertAttributeValidator() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String validatorName = this.getRequest().getParameter("validatorName");
if(validatorName != null && !validatorName.equalsIgnoreCase(""))
{
String validatorsXPath = "/xs:schema/xs:complexType[@name = 'Validation']/xs:annotation/xs:appinfo/form-validation/formset/form";
Node formNode = org.apache.xpath.XPathAPI.selectSingleNode(document.getDocumentElement(), validatorsXPath);
if(formNode != null)
{
Element element = (Element)formNode;
Element newField = document.createElement("field");
newField.setAttribute("property", this.attributeName);
newField.setAttribute("depends", validatorName);
String errorKey = null;
if(validatorName.equals("required"))
{
errorKey = "300"; //Required
}
else if(validatorName.equals("requiredif"))
{
errorKey = "300"; //Required
Element newVar = document.createElement("var");
Element varNameElement = createTextElement(document, "var-name", "dependent");
Element varValueElement = createTextElement(document, "var-value", "AttributeName");
newVar.appendChild(varNameElement);
newVar.appendChild(varValueElement);
newField.appendChild(newVar);
}
else if(validatorName.equals("matchRegexp"))
{
errorKey = "307"; //Invalid format
Element newVar = document.createElement("var");
Element varNameElement = createTextElement(document, "var-name", "regexp");
Element varValueElement = createTextElement(document, "var-value", ".*");
newVar.appendChild(varNameElement);
newVar.appendChild(varValueElement);
newField.appendChild(newVar);
}
else if(validatorName.equals("greaterThan") || validatorName.equals("greaterThanEquals") || validatorName.equals("lessThan") || validatorName.equals("lessThanEquals"))
{
errorKey = "306"; //Invalid value
Element newVar = document.createElement("var");
Element varNameElement = createTextElement(document, "var-name", "dependent");
Element varValueElement = createTextElement(document, "var-value", "AttributeName");
newVar.appendChild(varNameElement);
newVar.appendChild(varValueElement);
newField.appendChild(newVar);
}
Element newMessage = document.createElement("msg");
newMessage.setAttribute("name", validatorName);
newMessage.setAttribute("key", errorKey);
newField.appendChild(newMessage);
element.appendChild(newField);
}
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doUpdateAttributeValidatorArguments() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
int i = 0;
//String attributeValidatorName = this.getRequest().getParameter("attributeValidatorName");
String attributeValidatorIndex = this.getRequest().getParameter("attributeValidatorIndex");
Integer attributeValidatorIndexInteger = new Integer(attributeValidatorIndex);
String argumentName = this.getRequest().getParameter(i + "_argumentName");
while(argumentName != null && !argumentName.equalsIgnoreCase(""))
{
String argumentValue = this.getRequest().getParameter(i + "_argumentValue");
//String validatorsXPath = "/xs:schema/xs:complexType[@name = 'Validation']/xs:annotation/xs:appinfo/form-validation/formset/form/field[@property = '" + attributeName + "'][@depends = '" + attributeValidatorName + "']";
String validatorsXPath = "/xs:schema/xs:complexType[@name = 'Validation']/xs:annotation/xs:appinfo/form-validation/formset/form/field[@property = '" + attributeName + "'][" + attributeValidatorIndexInteger + "]";
Node fieldNode = org.apache.xpath.XPathAPI.selectSingleNode(document.getDocumentElement(), validatorsXPath);
if(fieldNode != null)
{
Element element = (Element)fieldNode;
NodeList nl = element.getElementsByTagName("var");
for(int nlIndex=0; nlIndex < nl.getLength(); nlIndex++)
{
Node node = (Node)nl.item(nlIndex);
element.removeChild(node);
}
Element newVar = document.createElement("var");
Element varNameElement = createTextElement(document, "var-name", argumentName);
Element varValueElement = createTextElement(document, "var-value", argumentValue);
newVar.appendChild(varNameElement);
newVar.appendChild(varValueElement);
element.appendChild(newVar);
}
i++;
argumentName = this.getRequest().getParameter(i + "_argumentName");
}
//Sets the message part
String msgText = this.getRequest().getParameter("errorMessage");
logger.info("msgText:" + msgText);
msgText = StringEscapeUtils.escapeXml(msgText);
logger.info("msgText:" + msgText);
//se=Du f�r inte 'ladda' inneh�llet med "s�nt"!<b>NU</b>;en=You cannot do 'this' or "that"
//String validatorsXPath = "/xs:schema/xs:complexType[@name = 'Validation']/xs:annotation/xs:appinfo/form-validation/formset/form/field[@property = '" + attributeName + "'][@depends = '" + attributeValidatorName + "']";
String validatorsXPath = "/xs:schema/xs:complexType[@name = 'Validation']/xs:annotation/xs:appinfo/form-validation/formset/form/field[@property = '" + attributeName + "'][" + attributeValidatorIndexInteger + "]";
Node fieldNode = org.apache.xpath.XPathAPI.selectSingleNode(document.getDocumentElement(), validatorsXPath);
logger.info("fieldNode:" + fieldNode);
if(fieldNode != null)
{
Element element = (Element)fieldNode;
NodeList nl1 = element.getElementsByTagName("msg");
for(int nlIndex=0; nlIndex < nl1.getLength(); nlIndex++)
{
Element messageElement = (Element)nl1.item(nlIndex);
if(currentContentTypeEditorViewLanguageCode != null && !currentContentTypeEditorViewLanguageCode.equals(""))
messageElement.setAttribute("key_" + currentContentTypeEditorViewLanguageCode, msgText);
else
messageElement.setAttribute("key", msgText);
}
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doDeleteAttributeValidator() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
int i = 0;
String attributeValidatorName = this.getRequest().getParameter("attributeValidatorName");
if(attributeValidatorName != null && !attributeValidatorName.equalsIgnoreCase(""))
{
String validatorsXPath = "/xs:schema/xs:complexType[@name = 'Validation']/xs:annotation/xs:appinfo/form-validation/formset/form/field[@property = '" + attributeName + "'][@depends = '" + attributeValidatorName + "']";
Node fieldNode = org.apache.xpath.XPathAPI.selectSingleNode(document.getDocumentElement(), validatorsXPath);
if(fieldNode != null)
{
Element element = (Element)fieldNode;
element.getParentNode().removeChild(element);
}
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
e.printStackTrace();
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
//-------------------------------------------------------------------------------------
// Methods dealing with extra keys
//
// TODO: I think it makes sense to move all methods dealing with ContentTypeDefinition XML
// TODO: into the ContentTypeDefinitionController, that way only ONE class knows about the
// TODO: XML structure and we can make adequate tests
//-------------------------------------------------------------------------------------
/**
* Gets the list of defined assetKeys.
*/
public List getDefinedAssetKeys()
{
return ContentTypeDefinitionController.getController().getDefinedAssetKeys(contentTypeDefinitionVO, true);
}
/**
* Gets the list of defined categoryKeys, also populate the category name for the UI.
*/
public List getDefinedCategoryKeys() throws Exception
{
List categoryKeys = ContentTypeDefinitionController.getController().getDefinedCategoryKeys(contentTypeDefinitionVO, true);
for (Iterator iter = categoryKeys.iterator(); iter.hasNext();)
{
CategoryAttribute info = (CategoryAttribute) iter.next();
if(info.getCategoryId() != null)
info.setCategoryName(getCategoryName(info.getCategoryId()));
else
info.setCategoryName("Undefined");
}
return categoryKeys;
}
/**
* Return the Category name, if we cannot find the category name (id not an int, bad id, etc)
* then do not barf, but return a user friendly name. This can happen if someone removes a
* category that is references by a content type definition.
*/
public String getCategoryName(Integer id)
{
try
{
return categoryController.findById(id).getName();
}
catch(SystemException e)
{
return "Category not found";
}
}
public String doInsertAssetKey() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
Element enumeration = ContentTypeDefinitionController.getController().createNewEnumerationKey(document, ContentTypeDefinitionController.ASSET_KEYS);
saveUpdatedDefinition(document);
}
catch(Exception e)
{
logger.warn("Error adding asset key: ", e);
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doInsertCategoryKey() throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
Element enumeration = ContentTypeDefinitionController.getController().createNewEnumerationKey(document, ContentTypeDefinitionController.CATEGORY_KEYS);
Element annotation = document.createElement("xs:annotation");
Element appinfo = document.createElement("xs:appinfo");
Element params = document.createElement("params");
enumeration.appendChild(annotation);
annotation.appendChild(appinfo);
appinfo.appendChild(params);
params.appendChild(createTextElement(document, "title", getRandomName()));
params.appendChild(createTextElement(document, "description", getRandomName()));
params.appendChild(createTextElement(document, "categoryId", ""));
saveUpdatedDefinition(document);
}
catch(Exception e)
{
logger.warn("Error adding categories key: ", e);
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doUpdateAssetKey() throws Exception
{
initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
updateAssetEnumerationKey(document, ContentTypeDefinitionController.ASSET_KEYS, getAssetKey(), getNewAssetKey(), this.isMandatory, this.description, this.maximumSize, this.allowedContentTypes, this.imageWidth, this.imageHeight, this.assetUploadTransformationsSettings);
saveUpdatedDefinition(document);
}
catch(Exception e)
{
logger.warn("Error updating asset key: ", e);
}
initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doUpdateCategoryKey() throws Exception
{
initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
Element enumeration = updateEnumerationKey(document, ContentTypeDefinitionController.CATEGORY_KEYS, getCategoryKey(), getNewCategoryKey());
if(enumeration != null)
{
Element title = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/title");
setTextElement(title, getSingleParameter("title"));
Element description = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/description");
setTextElement(description, getSingleParameter("description"));
Element categoryId = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/categoryId");
setTextElement(categoryId, getSingleParameter("categoryId"));
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
logger.warn("Error updating category key: ", e);
}
initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
public String doDeleteAssetKey() throws Exception
{
return deleteKey(ContentTypeDefinitionController.ASSET_KEYS, getAssetKey());
}
public String doDeleteCategoryKey() throws Exception
{
return deleteKey(ContentTypeDefinitionController.CATEGORY_KEYS, getCategoryKey());
}
private String deleteKey(String keyType, String key) throws Exception
{
this.initialize(getContentTypeDefinitionId());
try
{
Document document = createDocumentFromDefinition();
String attributesXPath = "/xs:schema/xs:simpleType[@name = '" + keyType + "']/xs:restriction/xs:enumeration[@value='" + key + "']";
NodeList anl = XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
if(anl != null && anl.getLength() > 0)
{
Element element = (Element)anl.item(0);
element.getParentNode().removeChild(element);
}
saveUpdatedDefinition(document);
}
catch(Exception e)
{
logger.warn("Error updating key: " + keyType, e);
}
this.initialize(getContentTypeDefinitionId());
return USE_EDITOR;
}
/**
* Returns the CategoryController, used by the ContentTypeDefinitionEditor
*/
public CategoryController getCategoryController()
{
return categoryController;
}
/**
* Gets the list of all system categories.
*/
public List getAllCategories() throws SystemException
{
return getCategoryController().getAllActiveCategories();
}
//-------------------------------------------------------------------------------------
// XML Helper Methods
//-------------------------------------------------------------------------------------
/**
* Consolidate the Document creation
*/
private Document createDocumentFromDefinition() throws SAXException, IOException
{
String contentTypeDefinitionString = this.contentTypeDefinitionVO.getSchemaValue();
InputSource xmlSource = new InputSource(new StringReader(contentTypeDefinitionString));
DOMParser parser = new DOMParser();
parser.parse(xmlSource);
return parser.getDocument();
}
/**
* Consolidate the update of a ContentTypeDefinition Document to the persistence mechanism
*/
private void saveUpdatedDefinition(Document document) throws ConstraintException, SystemException
{
StringBuffer sb = new StringBuffer();
XMLHelper.serializeDom(document.getDocumentElement(), sb);
this.contentTypeDefinitionVO.setSchemaValue(sb.toString());
ContentTypeDefinitionController.getController().update(contentTypeDefinitionVO);
}
/**
* Find an <xs:enumeration> element and update the key value.
* @return The Element if child changes are needed, null if the element is not found
*/
private Element updateEnumerationKey(Document document, String keyType, String oldKey, String newKey) throws TransformerException
{
String attributesXPath = "/xs:schema/xs:simpleType[@name = '" + keyType + "']/xs:restriction/xs:enumeration[@value='" + oldKey + "']";
NodeList anl = XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
if(anl != null && anl.getLength() > 0)
{
Element enumeration = (Element)anl.item(0);
enumeration.setAttribute("value", newKey);
return enumeration;
}
return null;
}
/**
* Find an <xs:enumeration> element and update the key value.
* @return The Element if child changes are needed, null if the element is not found
*/
private Element updateAssetEnumerationKey(Document document, String keyType, String oldKey, String newKey, Boolean isMandatory, String description, Integer maximumSize, String allowedContentTypes, String imageWidth, String imageHeight, String assetUploadTransformationsSettings) throws TransformerException
{
if(isMandatory == null)
isMandatory = new Boolean(false);
if(description == null)
description = "Undefined";
if(maximumSize == null)
maximumSize = new Integer(100);
if(allowedContentTypes == null)
allowedContentTypes = "*";
if(imageWidth == null)
imageWidth = "*";
if(imageHeight == null)
imageHeight = "*";
String attributesXPath = "/xs:schema/xs:simpleType[@name = '" + keyType + "']/xs:restriction/xs:enumeration[@value='" + oldKey + "']";
NodeList anl = XPathAPI.selectNodeList(document.getDocumentElement(), attributesXPath);
if(anl != null && anl.getLength() > 0)
{
Element enumeration = (Element)anl.item(0);
enumeration.setAttribute("value", newKey);
Element isMandatoryElement = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/isMandatory");
Element descriptionElement = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/description");
Element maximumSizeElement = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/maximumSize");
Element allowedContentTypesElement = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/allowedContentTypes");
Element imageWidthElement = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/imageWidth");
Element imageHeightElement = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/imageHeight");
Element assetUploadTransformationsSettingsElement = (Element)XPathAPI.selectSingleNode(enumeration, "xs:annotation/xs:appinfo/params/assetUploadTransformationsSettings");
if(isMandatoryElement == null && descriptionElement != null)
{
isMandatoryElement = createTextElement(document, "isMandatory", isMandatory.toString());
descriptionElement.getParentNode().appendChild(isMandatoryElement);
}
if(assetUploadTransformationsSettingsElement == null && descriptionElement != null)
{
assetUploadTransformationsSettingsElement = createTextElement(document, "assetUploadTransformationsSettings", assetUploadTransformationsSettings.toString());
descriptionElement.getParentNode().appendChild(assetUploadTransformationsSettingsElement);
}
if(descriptionElement == null)
{
Element annotation = document.createElement("xs:annotation");
Element appinfo = document.createElement("xs:appinfo");
Element params = document.createElement("params");
enumeration.appendChild(annotation);
annotation.appendChild(appinfo);
appinfo.appendChild(params);
descriptionElement = createTextElement(document, "description", getRandomName());
maximumSizeElement = createTextElement(document, "maximumSize", maximumSize.toString());
allowedContentTypesElement = createTextElement(document, "allowedContentTypes", allowedContentTypes);
imageWidthElement = createTextElement(document, "imageWidth", imageWidth);
imageHeightElement = createTextElement(document, "imageHeight", imageHeight);
isMandatoryElement = createTextElement(document, "isMandatory", isMandatory.toString());
assetUploadTransformationsSettingsElement = createTextElement(document, "assetUploadTransformationsSettings", assetUploadTransformationsSettings.toString());
params.appendChild(descriptionElement);
params.appendChild(maximumSizeElement);
params.appendChild(allowedContentTypesElement);
params.appendChild(imageWidthElement);
params.appendChild(imageHeightElement);
params.appendChild(isMandatoryElement);
}
else
{
setTextElement(isMandatoryElement, isMandatory.toString());
setTextElement(descriptionElement, description);
setTextElement(maximumSizeElement, maximumSize.toString());
setTextElement(allowedContentTypesElement, allowedContentTypes);
setTextElement(imageWidthElement, imageWidth);
setTextElement(imageHeightElement, imageHeight);
setTextElement(assetUploadTransformationsSettingsElement, assetUploadTransformationsSettings);
}
return enumeration;
}
return null;
}
/**
* Creates a new text element
*/
private Element createTextElement(Document document, String tagName, String value)
{
Element e = document.createElement(tagName);
e.appendChild(document.createTextNode(value));
return e;
}
/**
* Updates the text child of an element, creating it if it needs to.
*/
private void setTextElement(Element e, String value)
{
if(e.getFirstChild() != null)
e.getFirstChild().setNodeValue(value);
else
e.appendChild(e.getOwnerDocument().createTextNode(value));
}
/**
* Generates a random name
*/
private String getRandomName()
{
return "undefined" + (int)(Math.random() * 100);
}
//-------------------------------------------------------------------------------------
// Attribute Accessors
//-------------------------------------------------------------------------------------
public Integer getContentTypeDefinitionId()
{
return this.contentTypeDefinitionVO.getContentTypeDefinitionId();
}
public void setContentTypeDefinitionId(Integer contentTypeDefinitionId) throws Exception
{
this.contentTypeDefinitionVO.setContentTypeDefinitionId(contentTypeDefinitionId);
}
public String getTitle()
{
return this.title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getName()
{
return this.contentTypeDefinitionVO.getName();
}
public String getSchemaValue()
{
return this.contentTypeDefinitionVO.getSchemaValue();
}
public Integer getType()
{
return this.contentTypeDefinitionVO.getType();
}
public String getDetailPageResolverClass()
{
return this.contentTypeDefinitionVO.getDetailPageResolverClass();
}
public String getDetailPageResolverData()
{
return this.contentTypeDefinitionVO.getDetailPageResolverData();
}
public Integer getParentId()
{
return this.contentTypeDefinitionVO.getParentId();
}
public void setParentContentTypeDefinitionId(Integer parentContentTypeDefinitionId)
{
this.contentTypeDefinitionVO.setParentId(parentContentTypeDefinitionId);
}
/**
* This method returns the attributes in the content type definition for generation.
*/
public List<ContentTypeAttribute> getContentTypeAttributes()
{
return this.attributes;
}
public ContentTypeAttribute getAttribute()
{
return this.attribute;
}
public String getInputTypeId()
{
return inputTypeId;
}
public void setInputTypeId(String string)
{
inputTypeId = string;
}
public String getAttributeName()
{
return this.attributeName;
}
public void setAttributeName(String attributeName)
{
this.attributeName = attributeName;
}
public void setNewAttributeName(String newAttributeName)
{
this.newAttributeName = newAttributeName;
}
public String getAttributeParameterValueId()
{
return attributeParameterValueId;
}
public void setAttributeParameterValueId(String string)
{
attributeParameterValueId = string;
}
public String getAttributeParameterId()
{
return attributeParameterId;
}
public void setAttributeParameterId(String string)
{
attributeParameterId = string;
}
public String getAttributeParameterValueLabel()
{
return attributeParameterValueLabel;
}
public String getNewAttributeParameterValueId()
{
return newAttributeParameterValueId;
}
public void setAttributeParameterValueLabel(String string)
{
attributeParameterValueLabel = string;
}
public void setNewAttributeParameterValueId(String string)
{
newAttributeParameterValueId = string;
}
public String getAttributeParameterValueLocale()
{
return attributeParameterValueLocale;
}
public void setAttributeParameterValueLocale(String string)
{
attributeParameterValueLocale = string;
}
public String getAttributeToExpand()
{
return attributeToExpand;
}
public void setAttributeToExpand(String string)
{
attributeToExpand = string;
}
public String getCurrentContentTypeEditorViewLanguageCode()
{
return currentContentTypeEditorViewLanguageCode;
}
public void setCurrentContentTypeEditorViewLanguageCode(String string)
{
currentContentTypeEditorViewLanguageCode = string;
}
public List getAvailableLanguages()
{
return availableLanguages;
}
public String getAssetKey() { return assetKey; }
public void setAssetKey(String s) { assetKey = s; }
public String getNewAssetKey() { return newAssetKey; }
public void setNewAssetKey(String s) { newAssetKey = s; }
public String getCategoryKey() { return categoryKey; }
public void setCategoryKey(String s) { categoryKey = s; }
public String getNewCategoryKey() { return newCategoryKey; }
public void setNewCategoryKey(String s) { newCategoryKey = s; }
public String getErrorKey()
{
return "ContentTypeAttribute.updateAction";
}
public String getReturnAddress()
{
return "ViewListContentTypeDefinition.action";
}
public String getAllowedContentTypes()
{
return allowedContentTypes;
}
public void setAllowedContentTypes(String assetContentType)
{
this.allowedContentTypes = assetContentType;
}
public String getImageHeight()
{
return imageHeight;
}
public void setImageHeight(String imageHeight)
{
this.imageHeight = imageHeight;
}
public String getImageWidth()
{
return imageWidth;
}
public void setImageWidth(String imageWidth)
{
this.imageWidth = imageWidth;
}
public Integer getMaximumSize()
{
return maximumSize;
}
public void setMaximumSize(Integer maximumSize)
{
this.maximumSize = maximumSize;
}
public void setDescription(String description)
{
this.description = description;
}
public List getActivatedName()
{
return activatedName;
}
public Boolean getIsMandatory()
{
return isMandatory;
}
public void setIsMandatory(Boolean isMandatory)
{
this.isMandatory = isMandatory;
}
public String getAssetUploadTransformationsSettings()
{
return assetUploadTransformationsSettings;
}
public void setAssetUploadTransformationsSettings(String assetUploadTransformationsSettings)
{
this.assetUploadTransformationsSettings = assetUploadTransformationsSettings;
}
public Integer getTabToActivate()
{
return tabToActivate;
}
public void setTabToActivate(Integer tabToActivate)
{
this.tabToActivate = tabToActivate;
}
public Integer getVersionsToKeep()
{
return versionsToKeep;
}
public void setVersionsToKeep(Integer versionsToKeep)
{
this.versionsToKeep = versionsToKeep;
}
public List<ContentTypeDefinitionVO> getContentTypeDefinitions() throws Exception
{
return ContentTypeDefinitionController.getController().getContentTypeDefinitionVOList(ContentTypeDefinitionVO.CONTENT);
}
public List<ContentDetailPageResolver> getContentPageResolvers()
{
return ContentDetailPageResolversService.getService().geContentDetailPageResolvers();
}
}