Java tutorial
/******************************************************************************* ** ** Advanced Distributed Learning Co-Laboratory (ADL Co-Lab) Hub grants you ** ("Licensee") a non-exclusive, royalty free, license to use, modify and ** redistribute this software in source and binary code form, provided that ** i) this copyright notice and license appear on all copies of the software; ** and ii) Licensee does not utilize the software in a manner which is ** disparaging to ADL Co-Lab Hub. ** ** This software is provided "AS IS," without a warranty of any kind. ALL ** EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ** ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE ** OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ADL Co-Lab Hub AND ITS LICENSORS ** SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF ** USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO ** EVENT WILL ADL Co-Lab Hub OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, ** PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, ** INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE ** THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE ** SOFTWARE, EVEN IF ADL Co-Lab Hub HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH ** DAMAGES. ** *******************************************************************************/ package org.adl.validator.contentpackage; // native java imports import java.util.ArrayList; import java.util.List; import org.adl.logging.DetailedLogMessageCollection; import org.adl.parsers.dom.DOMTreeUtility; import org.adl.util.LogMessage; import org.adl.util.MessageType; import org.adl.util.Messages; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; /** * * <strong>Filename: </strong><br>ManifestMap.java<br><br> * * <strong>Description: </strong><br> A <code>ManifestMap</code> is a Data * Structure used to store manifest information that is necessary for for the * validation and processing of (Sub) manifests. * * @author ADL Technical Team */ public class ManifestMap implements IManifestMap { /** * */ private static final long serialVersionUID = 1L; /** * Logger object used for debug logging. */ private static Log log = LogFactory.getLog(ManifestMap.class); /** * The identifier attribute of the <manifest> element. */ private String mManifestId; /** * The identifier attributes of all <resource> elements that belong to the * <manifest> element of mManifestId. */ private List<String> mResourceIds; /** * The identifier attributes of all <item> elements that belong to the * <manifest> element of mManifestId. */ private List<String> mItemIds; /** * The identifier reference values of all <item> elements that belong to the * <manifest> element of mManifestId. */ private List<String> mItemIdrefs; /** * The identifier reference values of all <dependency> elements that belong to * the <manifest> element of mManifestId. */ private List<String> mDependencyIdrefs; /** * The ManifestMap objects for all (Sub) manifest elements. */ private List<ManifestMap> mManifestMaps; /** * The boolean describing if the manifest utilizes (Sub) manifest. */ private boolean mDoSubmanifestExist; /** * A List containing a list of Idrefs that reference subManifest elements. */ private List<String> mSubManifestIDrefs; /** * The identifier determining what type of (Sub) manifest is to be validated * for. If an item identifierref points to a (Sub) manifest identifier value, * than the (Sub) manifest qualifies as "content aggregation" for this * attribute value - allowing 1 and only 1 organization element in the * (Sub) manifest. If an item identfiierref value points to only a resource * identifier in a (Sub) manifest, the the (Sub) manifest qualifies as * "other" for this attribute - allowing 0 or 1 organization element in the * (Sub) manifest. */ private String mApplicationProfile; /** * The default constructor. */ public ManifestMap() { //mLogger = Logger.getLogger("org.adl.util.debug.validator"); mManifestId = ""; mResourceIds = new ArrayList<String>(); mItemIds = new ArrayList<String>(); mItemIdrefs = new ArrayList<String>(); mManifestMaps = new ArrayList<ManifestMap>(); mDoSubmanifestExist = false; mApplicationProfile = ""; mDependencyIdrefs = new ArrayList<String>(); mSubManifestIDrefs = new ArrayList<String>(); } /** * This method drives the recursive validation of the referencing of * identifierref values. It spans the validation of identifierrefs for * each identifierref value. * * @return - The List containing the identifierref value(s) that do not * reference valid identifers. * */ public List<String> checkAllIdReferences() { List<String> resultList = new ArrayList<String>(); String msgText = ""; String idrefValue = ""; boolean iItemdrefResult = false; if (!mItemIdrefs.isEmpty()) { int mItemIdrefsSize = mItemIdrefs.size(); for (int i = 0; i < mItemIdrefsSize; i++) { idrefValue = mItemIdrefs.get(i); if (!idrefValue.equals("")) { msgText = Messages.getString("ManifestMap.40", idrefValue); log.debug("INFO: " + msgText); DetailedLogMessageCollection.getInstance() .addMessage(new LogMessage(MessageType.INFO, msgText)); iItemdrefResult = checkIdReference(idrefValue, false); // track all idref values whose reference was not valid if (!iItemdrefResult) { msgText = Messages.getString("ManifestMap.43", idrefValue); log.debug("FAILED: " + msgText); DetailedLogMessageCollection.getInstance() .addMessage(new LogMessage(MessageType.FAILED, msgText)); resultList.add(idrefValue); } } } } if (!mDependencyIdrefs.isEmpty()) { int mDependencyIdrefsSize = mDependencyIdrefs.size(); for (int i = 0; i < mDependencyIdrefsSize; i++) { idrefValue = mDependencyIdrefs.get(i); if (!idrefValue.equals("")) { msgText = Messages.getString("ManifestMap.40", idrefValue); log.debug("INFO: " + msgText); DetailedLogMessageCollection.getInstance() .addMessage(new LogMessage(MessageType.INFO, msgText)); boolean iDependencydrefResult = checkIdReference(idrefValue, false); // track all idref values whose reference was not valid if (!iDependencydrefResult) { msgText = Messages.getString("ManifestMap.43", idrefValue); log.debug("FAILED: " + msgText); DetailedLogMessageCollection.getInstance() .addMessage(new LogMessage(MessageType.FAILED, msgText)); resultList.add(idrefValue); } } } } return resultList; } /** * This method validates that the incoming identifierref value properly * references a valid identifier. An error is thrown for identifierref * values that perform backwards or sideward referencing, or does not * reference an identifier value at all. * * @param iIdref the identifier reference being checked * * @param iInSubManifest if true then we treat it differently * * @return - The List containing the identifierref value(s) that do not * reference valid identifers. * */ public boolean checkIdReference(String iIdref, boolean iInSubManifest) { boolean result = false; String msgText = ""; // loop through resourceIds and compare to incoming idref value if (!mResourceIds.isEmpty()) { int mResourceIdsSize = mResourceIds.size(); for (int i = 0; i < mResourceIdsSize; i++) { String resourceId = mResourceIds.get(i); msgText = "Comparing " + iIdref + " to " + resourceId; log.debug(msgText); if (iIdref.equals(resourceId)) { result = true; msgText = Messages.getString("ManifestMap.55", iIdref); log.debug("PASSED: " + msgText); DetailedLogMessageCollection.getInstance() .addMessage(new LogMessage(MessageType.PASSED, msgText)); // set application profile to other only if it does not already // equal content aggregation. Other triggers the need for // an additional check that will allow 0 or more orgs. String currentAppProfile = getApplicationProfile(); if (!currentAppProfile.equals("contentaggregation") && iInSubManifest) { setApplicationProfile("other"); } else { setApplicationProfile("contentaggregation"); } msgText = "IDRef " + iIdref + " points to a resource " + resourceId + " , app profile is " + getApplicationProfile() + " for " + getManifestId(); log.debug(msgText); break; } } } // compare to manifestId of (Sub) manifest elements only if we didn't find // a match in the resources if (!result) { msgText = iIdref + " did not match the resourceIds, " + " now checking ManifestMaps"; log.debug(msgText); if (!mManifestMaps.isEmpty()) { int mManifestMapsSize = mManifestMaps.size(); for (int j = 0; j < mManifestMapsSize; j++) { ManifestMap map = mManifestMaps.get(j); String mapManifestId = map.getManifestId(); // first check to see if the idref references a manifest id if (iIdref.equals(mapManifestId)) { result = true; msgText = Messages.getString("ManifestMap.67", iIdref); log.debug("PASSED: " + msgText); DetailedLogMessageCollection.getInstance() .addMessage(new LogMessage(MessageType.PASSED, msgText)); // set application profile to be content aggregation, triggering // the check that 1 and only 1 org may exist. map.setApplicationProfile("contentaggregation"); msgText = "Idref " + iIdref + " points to a manifestId " + mapManifestId + " app profile is " + map.getApplicationProfile() + " for " + map.getManifestId(); log.debug(msgText); mSubManifestIDrefs.add(iIdref); // this allows us to break out of the for loop once we have // found a match break; } // than check to see if it references a resource in the sub else { if (!result) { //loop thru mapManifest to recuse with idref values result = map.checkIdReference(iIdref, true); } else { break; } } } } } msgText = "Returning " + result + "from checkIdReference"; log.debug(msgText); return result; } /** * Gives access to the String describing which Application Profile the * (Sub) manifest adheres to. * * @return - The boolean describing if the manifest utilizes (Sub) manifest. */ public String getApplicationProfile() { return mApplicationProfile; } /** * Gives access to the identifier reference values of all <dependency> * elements that belong to the <manifest> element of mManifestId. * * @return - The identifier reference values of all <dependency> elements * that belong to the <manifest> element of mManifestId. */ public List<String> getDependencyIdrefs() { return mDependencyIdrefs; } /** * Gives access to the boolean describing if the manifest utilizes * (Sub) manifest. * * @return - The boolean describing if the manifest utilizes (Sub) manifest. * */ public boolean getDoSubmanifestExist() { return mDoSubmanifestExist; } /** * Gives access to the identifier reference values of all <item> elements * that belong to the <manifest> element of mManifestId. * * @return - The identifier reference values of all <item> elements that * belong to the <manifest> element of mManifestId. */ public List<String> getItemIdrefs() { return mItemIdrefs; } /** * Gives access to the identifier attributes of all <item> elements that * belong to the <manifest> element of mManifestId. * * @return - The identifier attributes of all <item> elements that * belong to the <manifest> element of mManifestId. */ public List<String> getItemIds() { return mItemIds; } /** * Gives access to the identifier value of the <manifest> element. * * @return - The identifier value of the <manifest> element. */ public String getManifestId() { return mManifestId; } /** * Gives access to the ManifestMap objects for all (Sub) manifest elements. * * @return - The ManifestMap objects for all (Sub) manifest elements. */ public List<ManifestMap> getManifestMaps() { return mManifestMaps; } /** * Gives access to the identifier attributes of all <resource> elements that * belong to the <manifest> element of mManifestId. * * @return - The identifier attributes of all <resource> elements that * belong to the <manifest> element of mManifestId. */ public List<String> getResourceIds() { return mResourceIds; } /** * Gives access to the list of IDRefs that reference (Sub) manifest elements. * * @return - The ManifestMap objects for all (Sub) manifest elements. */ public List<String> getSubManifestIDrefs() { return mSubManifestIDrefs; } /** * This method populates the ManifestMap object by traversing down * the document node and storing all information necessary for the validation * of (Sub) manifests. Information stored for each manifest element includes: * manifest identifiers,item identifers, item identifierrefs, and * resource identifiers * * @param iNode the node being checked. All checks will depend on the type of node * being evaluated * * @return - The boolean describing if the ManifestMap object(s) has been * populated properly. */ public boolean populateManifestMap(Node iNode) { // looks exactly like prunetree as we walk down the tree log.debug("populateManifestMap"); boolean result = true; // is there anything to do? if (iNode == null) { result = false; return result; } int type = iNode.getNodeType(); switch (type) { case Node.PROCESSING_INSTRUCTION_NODE: { break; } case Node.DOCUMENT_NODE: { Node rootNode = ((Document) iNode).getDocumentElement(); result = populateManifestMap(rootNode) && result; break; } case Node.ELEMENT_NODE: { String parentNodeName = iNode.getLocalName(); if (parentNodeName.equalsIgnoreCase("manifest")) { // We are dealing with an IMS <manifest> element, get the IMS // CP identifier for the <manifest> elememnt mManifestId = DOMTreeUtility.getAttributeValue(iNode, "identifier"); log.debug( "ManifestMap:populateManifestMap, " + "Just stored a Manifest Id value of " + mManifestId); // Recurse to populate mItemIdrefs and mItemIds // Find the <organization> elements Node orgsNode = DOMTreeUtility.getNode(iNode, "organizations"); if (orgsNode != null) { List<Node> orgElems = DOMTreeUtility.getNodes(orgsNode, "organization"); log.debug("ManifestMap:populateManifestMap, " + "Number of <organization> elements: " + orgElems.size()); if (!orgElems.isEmpty()) { int orgElemsSize = orgElems.size(); for (int i = 0; i < orgElemsSize; i++) { List<Node> itemElems = DOMTreeUtility.getNodes(orgElems.get(i), "item"); log.debug("ManifestMap:populateManifestMap, " + "Number of <item> elements: " + itemElems.size()); if (!itemElems.isEmpty()) { int itemElemsSize = itemElems.size(); for (int j = 0; j < itemElemsSize; j++) { result = populateManifestMap((itemElems.get(j))) && result; } } } } } //recurse to populate mResourceIds Node resourcesNode = DOMTreeUtility.getNode(iNode, "resources"); if (resourcesNode != null) { List<Node> resourceElems = DOMTreeUtility.getNodes(resourcesNode, "resource"); log.debug("ManifestMap:populateManifestMap, " + "Number of <resource> elements: " + resourceElems.size()); int resourceElemsSize = resourceElems.size(); for (int k = 0; k < resourceElemsSize; k++) { result = populateManifestMap((resourceElems.get(k))) && result; } } //recurse to populate mManifestMaps //find the <manifest> elements (a.k.a sub-manifests) List<Node> subManifests = DOMTreeUtility.getNodes(iNode, "manifest"); log.debug("ManifestMap:populateManifestMap, " + "Number of (Sub) manifest elements: " + subManifests.size()); if (!subManifests.isEmpty()) { mDoSubmanifestExist = true; int subManifestSize = subManifests.size(); for (int l = 0; l < subManifestSize; l++) { ManifestMap manifestMapObject = new ManifestMap(); result = manifestMapObject.populateManifestMap(subManifests.get(l)) && result; mManifestMaps.add(manifestMapObject); } } } else if (parentNodeName.equalsIgnoreCase("item")) { //store item identifier value String itemId = DOMTreeUtility.getAttributeValue(iNode, "identifier"); mItemIds.add(itemId); log.debug("ManifestMap:populateManifestMap, " + "Just stored an Item Id value of " + itemId); //store item identifier reference value String itemIdref = DOMTreeUtility.getAttributeValue(iNode, "identifierref"); mItemIdrefs.add(itemIdref); log.debug("ManifestMap:populateManifestMap, " + "Just stored an Item Idref value of " + itemIdref); //recurse to populate all child item elements List<Node> items = DOMTreeUtility.getNodes(iNode, "item"); if (!items.isEmpty()) { int itemsSize = items.size(); for (int z = 0; z < itemsSize; z++) { result = populateManifestMap(items.get(z)) && result; } } } else if (parentNodeName.equalsIgnoreCase("resource")) { //store resource identifier value String resourceId = DOMTreeUtility.getAttributeValue(iNode, "identifier"); // convert to lower so case sensativity does not play a role mResourceIds.add(resourceId); log.debug("ManifestMap:populateManifestMap, " + "Just stored a Resource Id value of " + resourceId); // populate <dependency> element List<Node> dependencyElems = DOMTreeUtility.getNodes(iNode, "dependency"); int dependencyElemsSize = dependencyElems.size(); for (int w = 0; w < dependencyElemsSize; w++) { Node dependencyElem = dependencyElems.get(w); //store resource identifier value String dependencyIdref = DOMTreeUtility.getAttributeValue(dependencyElem, "identifierref"); mDependencyIdrefs.add(dependencyIdref); log.debug("ManifestMap:populateManifestMap, " + "Just stored a Dependency Idref value of " + mDependencyIdrefs); } } break; } // handle entity reference nodes case Node.ENTITY_REFERENCE_NODE: { break; } // text case Node.COMMENT_NODE: { break; } case Node.CDATA_SECTION_NODE: { break; } case Node.TEXT_NODE: { break; } } log.debug("populateManifestMap"); return result; } /** * Gives access to the String describing which Application Profile the * (Sub) manifest adheres to. * * @param iApplicationProfile The indicator of the Application Profile */ public void setApplicationProfile(String iApplicationProfile) { mApplicationProfile = iApplicationProfile; } }