/** * EasySOA Registry * Copyright 2011-2013 Open Wide * * This program 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 3 of the License, or * (at your option) any later version. * * This program 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. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contact : easysoa-dev@googlegroups.com */ package org.easysoa.registry.rest; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import org.codehaus.jackson.annotate.JsonAutoDetect; import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.annotate.JsonProperty; import org.codehaus.jackson.annotate.JsonSubTypes; import org.codehaus.jackson.annotate.JsonTypeInfo; import org.codehaus.jackson.annotate.JsonTypeInfo.As; import org.codehaus.jackson.annotate.JsonTypeInfo.Id; import org.easysoa.registry.rest.jackson.JacksonModelHelper; import org.easysoa.registry.rest.jackson.SoaDateType; import org.easysoa.registry.rest.jackson.SoaListType; import org.easysoa.registry.rest.jackson.SoaMapType; import org.easysoa.registry.rest.jaxb.JaxbModelHelper; import org.easysoa.registry.rest.jaxb.SoaNodeProperties; import org.easysoa.registry.types.SoaNode; import org.easysoa.registry.types.SubprojectNode; import org.easysoa.registry.types.ids.SoaNodeId; import org.easysoa.registry.utils.ListUtils; /** * Models all information about an SOA node. * * Uses JacksonModelHelper & JaxbModelHelper for respectively JSON/Jackson * & XML/JAXB serialization of its generic properties. * * @author mdutoo * */ @XmlRootElement(name = "soaNodeInformation") @XmlAccessorType(XmlAccessType.FIELD) @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE) public class SoaNodeInformation implements SoaNode { protected SoaNodeId id; /** * SoaNodeInformation properties i.e. Nuxeo's without Blobs. * Not serialized directly, but through (jackson or jaxb) model builder getter & setter */ @JsonIgnore @XmlTransient protected Map<String, Serializable> properties; protected List<SoaNodeId> parentDocuments; protected SoaNodeInformation() { } public SoaNodeInformation(SoaNodeId id, Map<String, Serializable> properties, List<SoaNodeId> parentDocuments) { this.id = id; this.properties = (properties == null) ? new HashMap<String, Serializable>() : properties; if (id != null) { this.properties.putAll(id.getDefaultPropertyValues()); } // else edge Subproject case this.parentDocuments = (parentDocuments == null) ? new ArrayList<SoaNodeId>() : parentDocuments; } /** * JAXB model getter for SoaNodeInformation properties (Nuxeo's without Blobs). * (and also a tentative jackson setup). * because SoaNodeProperties * @return */ @XmlElement(name="properties") public SoaNodeProperties getJaxbProperties() { return JaxbModelHelper.toSoaNodeProperties(this.properties); } /** * JAXB model setter for SoaNodeInformation properties (Nuxeo's without Blobs). * (and also a tentative jackson setup). * See conf on getter. * @param soaNodeProperties */ public void setJaxbProperties(SoaNodeProperties soaNodeProperties) { this.properties = JaxbModelHelper.fromSoaNodeProperties(soaNodeProperties); } /** * Jackson model getter for SoaNodeInformation properties (Nuxeo's without Blobs). * Its @JsonTypeInfo(use = Id.NAME, include = As.WRAPPER_OBJECT) lets contained * objects be written as tercely as possible (ex. of int : 1, to compare with * ex. of long : {Long:1}). Alternatively, Id.MINIMAL_CLASS is powerful but far * less pretty (shows full Java class names), and As.PROPERTY is not as terce * (additional "property=" for ALL objects including ex. int). * Its @JsonSubTypes is required, else error ex. : * Could not resolve type id 'Long' into a subtype of [simple type, class java.io.Serializable] * @return */ @JsonProperty("properties") @JsonSubTypes({ @JsonSubTypes.Type(String.class), @JsonSubTypes.Type(SoaDateType.class), @JsonSubTypes.Type(SoaMapType.class), @JsonSubTypes.Type(SoaListType.class), @JsonSubTypes.Type(Integer.class), @JsonSubTypes.Type(Long.class), @JsonSubTypes.Type(Float.class), @JsonSubTypes.Type(Double.class), @JsonSubTypes.Type(Boolean.class) }) @JsonTypeInfo(use = Id.NAME, include = As.WRAPPER_OBJECT) public Map<String, Serializable> getJacksonProperties() { return JacksonModelHelper.toJacksonProperties(properties); } /** * Jackson model setter for SoaNodeInformation properties (Nuxeo's without Blobs). * See getter. * @param properties */ @JsonProperty("properties") @JsonSubTypes({ @JsonSubTypes.Type(String.class), @JsonSubTypes.Type(SoaDateType.class), @JsonSubTypes.Type(SoaMapType.class), @JsonSubTypes.Type(SoaListType.class), @JsonSubTypes.Type(Integer.class), @JsonSubTypes.Type(Long.class), @JsonSubTypes.Type(Float.class), @JsonSubTypes.Type(Double.class), @JsonSubTypes.Type(Boolean.class) }) @JsonTypeInfo(use = Id.NAME, include = As.WRAPPER_OBJECT) public void setJacksonProperties(Map<String, Serializable> properties) { this.properties = JacksonModelHelper.fromJacksonProperties(properties); } @Override public SoaNodeId getSoaNodeId() { return id; } public void setSoaNodeId(SoaNodeId id) { this.id = id; } @Override public String getSoaName() { return id.getName(); } @Override public String getSubprojectId() { return (String) properties.get(SubprojectNode.XPATH_SUBPROJECT); } public Map<String, Serializable> getProperties() { return properties; } public void setProperties(Map<String, Serializable> properties) { this.properties = properties; } @Override public Object getProperty(String xpath) throws Exception { return this.properties.get(xpath); } @Override public void setProperty(String xpath, Serializable value) throws Exception { this.properties.put(xpath, value); } public List<SoaNodeId> getParentDocuments() { return parentDocuments; } public void setParentDocuments(List<SoaNodeId> correlatedDocuments) { this.parentDocuments = correlatedDocuments; } public void addParentDocument(SoaNodeId correlatedDocument) { this.parentDocuments.add(correlatedDocument); } @Override public String getName() { return (String) properties.get(SoaNode.XPATH_NAME); } @Override public String getTitle() { return (String) properties.get(SoaNode.XPATH_TITLE); } @Override public void setTitle(String title) { properties.put(SoaNode.XPATH_TITLE, title); } @Override public String getDescription() { return (String) properties.get(SoaNode.XPATH_DESCRIPTION); } @Override public void setDescription(String description) { properties.put(SoaNode.XPATH_DESCRIPTION, description); } @JsonIgnore // else serializable event though JsonAutoDetect, why ?? @Override public boolean isPlaceholder() throws Exception { return (Boolean) properties.get(SoaNode.XPATH_TITLE); } @JsonIgnore @Override public void setIsPlaceholder(boolean isPlaceholder) throws Exception { properties.put(SoaNode.XPATH_TITLE, isPlaceholder); } @Override public String toString() { return this.id.toString(); } @Override public List<SoaNodeId> getParentIds() throws Exception { Serializable[] parentsIdsArray = (Serializable[]) properties.get(XPATH_PARENTSIDS); List<String> parentsIdsStringList = ListUtils.toStringList(parentsIdsArray); List<SoaNodeId> parentsIds = new ArrayList<SoaNodeId>(); for (String parentIdString : parentsIdsStringList) { SoaNodeId parentId = SoaNodeId.fromString(parentIdString); if (parentId != null) { parentsIds.add(parentId); } } return parentsIds; } @Override public SoaNodeId getParentOfType(String doctype) throws Exception { Serializable[] parentsIdsArray = (Serializable[]) properties.get(XPATH_PARENTSIDS); for (Serializable parentIdString : parentsIdsArray) { SoaNodeId parentId = SoaNodeId.fromString((String) parentIdString); if (parentId.getType().equals(doctype)) { return parentId; } } return null; } @Override public List<SoaNodeId> getParentsOfType(String doctype) throws Exception { Serializable[] parentsIdsArray = (Serializable[]) properties.get(XPATH_PARENTSIDS); List<SoaNodeId> res = new ArrayList<SoaNodeId>(parentsIdsArray.length); for (Serializable parentIdString : parentsIdsArray) { SoaNodeId parentId = SoaNodeId.fromString((String) parentIdString); if (parentId.getType().equals(doctype)) { res.add(parentId); } } return res; } @Override public void setParentIds(List<SoaNodeId> parentIds) throws Exception { List<String> parentsIdsStringList = new ArrayList<String>(); for (SoaNodeId parentId : parentIds) { parentsIdsStringList.add(parentId.toString()); } properties.put(XPATH_PARENTSIDS, (Serializable) parentsIdsStringList); } @Override public String getUuid() throws Exception { return (String) properties.get(XPATH_UUID); } }