Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,21 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/** Catalogs all server communities by querying the ../sys_cmpCommunities/communities.xml app. */
public class PSCommunityCataloger {
/**
* Catalogs all server communities by querying the ../sys_cmpCommunities/communities.xml app.
*
* <p>Declared {@code final} with a {@code final} collection field and a pure static XML parse
* helper so constructors never call overridable instance methods (javac {@code this-escape}).
*/
public final class PSCommunityCataloger {
/**
* Default constructor. Does nothing. Must be followed by call to fromXml() method. This is useful
* only to build an object in the fly means the state information might not come from the Rhythmyx
* server.
*/
public PSCommunityCataloger() {}
public PSCommunityCataloger() {
m_collCommunities = new ArrayList<>();
}

/**
* Constructor meant to be used in the context of an applet. This may not work in other contexts
Expand All @@ -48,11 +55,10 @@ public PSCommunityCataloger() {}
* @throws PSCmsException if request to server to get the data fails for any reason.
*/
public PSCommunityCataloger(URL urlBase) throws PSCmsException {
m_collCommunities.clear();
try {
URL url = new URL(urlBase, "sys_cmpCommunities/communities.xml");
Document doc = PSXmlDocumentBuilder.createXmlDocument(url.openStream(), false);
fromXml(doc.getDocumentElement());
m_collCommunities = parseCommunities(doc.getDocumentElement());
} catch (Exception e) {
throw new PSCmsException(IPSContentExplorerErrors.CATALOG_ERROR, e.getMessage());
}
Expand All @@ -62,24 +68,15 @@ public PSCommunityCataloger(URL urlBase) throws PSCmsException {
* Implementation of the interface method.
*/
public Object clone() {
PSCommunityCataloger clone = null;
try {
clone = (PSCommunityCataloger) super.clone();

Collection<Community> clonedComm = new ArrayList<>();
PSCommunityCataloger clone = new PSCommunityCataloger();

for (Community community : m_collCommunities) {
Object communityClone = community.clone();
if (communityClone instanceof Community) {
clonedComm.add((Community) communityClone);
}
for (Community community : m_collCommunities) {
Object communityClone = community.clone();
if (communityClone instanceof Community) {
clone.m_collCommunities.add((Community) communityClone);
}

clone.m_collCommunities = clonedComm;

} catch (CloneNotSupportedException e) {
// ????
}

return clone;
}

Expand All @@ -91,20 +88,18 @@ public boolean equals(Object object) {
PSCommunityCataloger that = (PSCommunityCataloger) object;

return new org.apache.commons.lang3.builder.EqualsBuilder()
.appendSuper(super.equals(object))
.append(m_collCommunities, that.m_collCommunities)
.isEquals();
}

public int hashCode() {
return new org.apache.commons.lang3.builder.HashCodeBuilder(17, 37)
.appendSuper(super.hashCode())
.append(m_collCommunities)
.toHashCode();
}

/** Represents a single community. */
public static class Community {
public static final class Community {
/**
* Default constructor. Does nothing. Must be followed by call to fromXml() method. This is
* useful only to build an object in the fly means the state information might not come from the
Expand All @@ -130,15 +125,16 @@ public Community(int id, String name, String description) {
}

/**
* Constructor that calls fromXml.
* Constructor that loads from XML via the private apply helper (no overridable method on
* {@code this} during construction).
*
* @param elemRoot the element that contains data for a single community, never <code>null
* </code>
* @throws PSUnknownNodeTypeException if the supplied element does not match the expected
* schema.
*/
public Community(Element elemRoot) throws PSUnknownNodeTypeException {
fromXml(elemRoot);
applyFromXml(elemRoot);
}

/**
Expand All @@ -150,6 +146,14 @@ public Community(Element elemRoot) throws PSUnknownNodeTypeException {
* schema.
*/
public void fromXml(Element elemRoot) throws PSUnknownNodeTypeException {
applyFromXml(elemRoot);
}

/**
* Applies community XML fields onto this instance. Private so constructors do not invoke an
* overridable method.
*/
private void applyFromXml(Element elemRoot) throws PSUnknownNodeTypeException {
PSXMLDomUtil.checkNode(elemRoot, XML_ELEM_LIST);
Element el = PSXMLDomUtil.getFirstElementChild(elemRoot, XML_ELEM_COMMUNITYNAME);
m_communityName = PSXMLDomUtil.getElementData(el);
Expand Down Expand Up @@ -207,19 +211,7 @@ public boolean equals(Object obj) {
* Implementation of the interface method
*/
public Object clone() {
Community clone = null;
try {
clone = (Community) super.clone();

clone.m_communityName = m_communityName;
clone.m_communityId = m_communityId;
clone.m_communityDesc = m_communityDesc;

} catch (CloneNotSupportedException e) {
// ????
}

return clone;
return new Community(m_communityId, m_communityName, m_communityDesc);
}

/*
Expand Down Expand Up @@ -254,7 +246,23 @@ public int hashCode() {
* @throws PSUnknownNodeTypeException if the supplied element does not match the expected schema.
*/
public void fromXml(Element elemRoot) throws PSUnknownNodeTypeException {
Collection<Community> parsed = parseCommunities(elemRoot);
m_collCommunities.clear();
m_collCommunities.addAll(parsed);
}

/**
* Pure parse of community catalog XML into a new mutable collection. Package-private for unit
* tests; used by the URL constructor and {@link #fromXml(Element)} so constructors never call
* overridable instance methods.
*
* @param elemRoot the root element containing the communities data, never <code>null</code>
* @return newly allocated collection of communities, never <code>null</code>
* @throws PSUnknownNodeTypeException if the element does not match the expected schema
*/
static Collection<Community> parseCommunities(Element elemRoot)
throws PSUnknownNodeTypeException {
Collection<Community> communities = new ArrayList<>();

PSXMLDomUtil.checkNode(elemRoot, XML_ELEM_ROOT);

Expand All @@ -266,10 +274,10 @@ public void fromXml(Element elemRoot) throws PSUnknownNodeTypeException {
Node n = nl.item(i);
if (n.getNodeType() != Node.ELEMENT_NODE) continue;

Community comm = new Community((Element) n);

m_collCommunities.add(comm);
communities.add(new Community((Element) n));
}

return communities;
}

/**
Expand All @@ -295,8 +303,11 @@ public static Community createCommunity(int id, String name, String description)
return new Community(id, name, description);
}

/** collection of cataloged Community instances */
private Collection<Community> m_collCommunities = new ArrayList<>();
/**
* Collection of cataloged Community instances. Final reference; contents are replaced via clear /
* addAll so constructors never reassign after init (javac {@code this-escape}).
*/
private final Collection<Community> m_collCommunities;

/** The XML root element name containing all cataloged communities. */
public static final String XML_ELEM_ROOT = "communities";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,18 @@
*
* <p>Note, the communities in the mapper may not contain all communities that are defined in the
* server. It only contains the commmunities which contain a list of non empty content types.
*
* <p>Declared {@code final} with a {@code final} map field and pure static XML parse helpers so
* constructors never call overridable instance methods (javac {@code this-escape}).
*/
public class PSCommunityContentTypeMapperCataloger {
public final class PSCommunityContentTypeMapperCataloger {
/**
* Default constructor for offline construction and tests. Must be followed by {@link
* #fromXml(Element)}.
*/
PSCommunityContentTypeMapperCataloger() {}
PSCommunityContentTypeMapperCataloger() {
m_commCtMapper = new HashMap<>();
}

/**
* Constructor meant to be used in the context of an applet. This may not work in other contexts
Expand All @@ -59,7 +64,7 @@ public PSCommunityContentTypeMapperCataloger(URL urlBase) throws PSCmsException
try {
URL url = new URL(urlBase, "sys_commSupport/CommunityContentTypeMapper.xml");
Document doc = PSXmlDocumentBuilder.createXmlDocument(url.openStream(), false);
fromXml(doc.getDocumentElement());
m_commCtMapper = parseMapper(doc.getDocumentElement());
} catch (Exception e) {
throw new PSCmsException(IPSContentExplorerErrors.CATALOG_ERROR, e.getMessage());
}
Expand Down Expand Up @@ -117,7 +122,21 @@ public Collection<PSCommunityCataloger.Community> getCompatibleCommunities(
* @exception PSUnknownNodeTypeException if the XML does not conform its DTD.
*/
void fromXml(Element elemRoot) throws PSUnknownNodeTypeException {
Map<PSCommunityCataloger.Community, Collection<PSEntry>> parsed = parseMapper(elemRoot);
m_commCtMapper.clear();
m_commCtMapper.putAll(parsed);
}

/**
* Pure parse of community/content-type mapper XML into a new map. Package-private for unit tests.
*
* @param elemRoot the XML representation, assumed not <code>null</code>
* @return newly allocated map, never <code>null</code>
* @throws PSUnknownNodeTypeException if the XML does not conform its DTD
*/
static Map<PSCommunityCataloger.Community, Collection<PSEntry>> parseMapper(Element elemRoot)
throws PSUnknownNodeTypeException {
Map<PSCommunityCataloger.Community, Collection<PSEntry>> mapper = new HashMap<>();

PSXMLDomUtil.checkNode(elemRoot, XML_ELEM_ROOT);

Expand All @@ -130,28 +149,22 @@ void fromXml(Element elemRoot) throws PSUnknownNodeTypeException {
Node mapping = nl.item(i);
if (mapping.getNodeType() != Node.ELEMENT_NODE) continue;

addMapping((Element) mapping);
addMapping(mapper, (Element) mapping);
}

return mapper;
}

/**
* Adds the community and content type mapping from the supplied XML element.
*
* <p>The DTD of its XML represenation is:
*
* <pre><code>
* &lt;!ELEMENT ContentType EMPTY>
* &lt;!ATTLIST ContentType name CDATA #REQUIRED>
* &lt;!ATTLIST ContentType id CDATA #REQUIRED>
* &lt;!ELEMENT CommunityContentTypeMapping (ContentType* )>
* &lt;!ATTLIST CommunityContentTypeMapping communityName CDATA #REQUIRED>
* &lt;!ATTLIST CommunityContentTypeMapping communityId CDATA #REQUIRED>
* </code></pre>
* Adds the community and content type mapping from the supplied XML element into {@code mapper}.
*
* @param mapper the destination map, never <code>null</code>
* @param mapping the XML representation of the mapping. Assume not <code>null</code>.
* @throws PSUnknownNodeTypeException if the element does not conform the DTD.
*/
private void addMapping(Element mapping) throws PSUnknownNodeTypeException {
private static void addMapping(
Map<PSCommunityCataloger.Community, Collection<PSEntry>> mapper, Element mapping)
throws PSUnknownNodeTypeException {
// get the community
String name = PSXMLDomUtil.checkAttribute(mapping, XML_ATTR_COMMUNITYNAME, true);
int id = PSXMLDomUtil.checkAttributeInt(mapping, XML_ATTR_COMMUNITYID, true);
Expand All @@ -172,10 +185,10 @@ private void addMapping(Element mapping) throws PSUnknownNodeTypeException {
ctElem = PSXMLDomUtil.getNextElementSibling(ctElem);
}

if (m_commCtMapper.containsKey(community)) {
m_commCtMapper.get(community).addAll(ctSet);
if (mapper.containsKey(community)) {
mapper.get(community).addAll(ctSet);
} else {
m_commCtMapper.put(community, ctSet);
mapper.put(community, ctSet);
}
}

Expand All @@ -198,10 +211,9 @@ private PSCommunityCataloger.Community getCommunity(Integer id) {
* It maps a community to a list of content types which are specified for the community. The map
* key is <code>PSCommunityCataloger.Community</code> object. The map value is a <code>
* Collection</code> of zero or more <code>PSEntry</code> object, which contain the id and name of
* the content type.
* the content type. Final reference; contents replaced via clear / putAll.
*/
private Map<PSCommunityCataloger.Community, Collection<PSEntry>> m_commCtMapper =
new HashMap<>();
private final Map<PSCommunityCataloger.Community, Collection<PSEntry>> m_commCtMapper;

/** Constants for XML elements and attributes */
private static final String XML_ELEM_ROOT = "CommunityContentTypeMapper";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,20 @@
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/** This class catalogs all global template names found in rhythmyx. */
public class PSGlobalTemplateCataloger {
/**
* This class catalogs all global template names found in rhythmyx.
*
* <p>Declared {@code final} with a {@code final} collection field and a pure static XML parse
* helper so constructors never call overridable instance methods (javac {@code this-escape}).
*/
public final class PSGlobalTemplateCataloger {
/**
* Default constructor for offline construction and tests. Must be followed by {@link
* #fromXml(Element)}.
*/
PSGlobalTemplateCataloger() {}
PSGlobalTemplateCataloger() {
m_globalTemplates = new ArrayList<>();
}

/**
* Constructs a new global template cataloger.
Expand All @@ -50,7 +57,7 @@ public PSGlobalTemplateCataloger(URL urlBase) throws PSCmsException {
URL url = new URL(urlBase, "sys_psxCataloger/getGlobalTemplates.xml");
Document doc = PSXmlDocumentBuilder.createXmlDocument(url.openStream(), false);

fromXml(doc.getDocumentElement());
m_globalTemplates = parseGlobalTemplates(doc.getDocumentElement());
} catch (Exception e) {
throw new PSCmsException(IPSContentExplorerErrors.CATALOG_ERROR, e.getMessage());
}
Expand All @@ -66,15 +73,33 @@ public PSGlobalTemplateCataloger(URL urlBase) throws PSCmsException {
* @throws PSUnknownNodeTypeException for any unknown XML node.
*/
void fromXml(Element elemRoot) throws PSUnknownNodeTypeException {
Collection<String> parsed = parseGlobalTemplates(elemRoot);
m_globalTemplates.clear();
m_globalTemplates.addAll(parsed);
}

/**
* Pure parse of global template catalog XML into a new mutable collection. Package-private for
* unit tests.
*
* @param elemRoot the XML element from which to load the global template names, assumed not
* <code>null</code>
* @return newly allocated collection of template names, never <code>null</code>
* @throws PSUnknownNodeTypeException for any unknown XML node
*/
static Collection<String> parseGlobalTemplates(Element elemRoot)
throws PSUnknownNodeTypeException {
Collection<String> templates = new ArrayList<>();

PSXMLDomUtil.checkNode(elemRoot, ROOT_ELEM);

NodeList templates = elemRoot.getElementsByTagName(TEMPLATE_ELEM);
for (int i = 0; i < templates.getLength(); i++) {
Element template = (Element) templates.item(i);
m_globalTemplates.add(template.getAttribute(NAME_ATTR));
NodeList templateNodes = elemRoot.getElementsByTagName(TEMPLATE_ELEM);
for (int i = 0; i < templateNodes.getLength(); i++) {
Element template = (Element) templateNodes.item(i);
templates.add(template.getAttribute(NAME_ATTR));
}

return templates;
}

/**
Expand All @@ -88,10 +113,10 @@ public Collection<String> getGlobalTemplates() {
}

/**
* The collection of all global template names, reset with each call to {@link #fromXml(Element)},
* never <code>null</code>, may be empty.
* The collection of all global template names. Final reference; contents replaced via clear /
* addAll with each call to {@link #fromXml(Element)}.
*/
private Collection<String> m_globalTemplates = new ArrayList<>();
private final Collection<String> m_globalTemplates;

// private XML constants
private static final String ROOT_ELEM = "GlobalTemplates";
Expand Down
Loading
Loading