// // Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s). // All rights reserved. // package openadk.library.policy; import openadk.library.Agent; import openadk.library.Zone; import openadk.library.tools.cfg.AgentConfig; import openadk.util.XMLUtils; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.Pointer; import org.w3c.dom.Element; /** * Represents the default policy engine used by the ADK. Policy is controlled * by entries in the agent's XML configuration file or default policy.<p> * * <p>Policy entries can be set at the Agent, Template, or Zone level in the agent's * configuration file. If the {@link AgentConfig} class is not used to configure the * agent, this class provides default policies prescribed by the ADK.</p> * * <p>Here is an example of setting request policy using the agent configuration * file. The <code><Policy></code> element can be placed using a zone, template * or agent node in the config file. * <pre> * <policy> * <!-- Set the policies for requesting data--> * <requestpolicy> * <object name="*"> * <!-- For all objects, request data using SIF 1.5r1--> * <version>1.5r1</version> * </object> * <object name="Assessment"> * <!-- Override the default policy for the Assessment object and request it * using 2.* and using a specific source id --> * <version>2.*</version> * <sourceId>AssessmentAgent</sourceId> * </object> * </requestpolicy> * </policy> * </pre> * </p> * * @author Andrew Elmhorst * @version ADK 2.1 */ public class ADKDefaultPolicy extends PolicyFactory { private AgentConfig fConfig; public ADKDefaultPolicy( Agent agent ){ if( agent != null ){ Object source = agent.getConfigurationSource(); if( source != null && source instanceof AgentConfig ){ fConfig = (AgentConfig)source; } } } /* (non-Javadoc) * @see openadk.library.policy.PolicyFactory#getRequestPolicy(openadk.library.Zone, openadk.library.ElementDef) */ @Override public ObjectRequestPolicy getRequestPolicy( Zone zone, String objectName) { Element policyElement = getPolicyElement( zone.getZoneId(), "requestPolicy", objectName ); if( policyElement != null ){ ObjectRequestPolicy policy = new ObjectRequestPolicy( objectName ); policy.setRequestSourceId( XMLUtils.getElementTextValue( policyElement, "sourceId" ) ); policy.setRequestVersions( XMLUtils.getElementTextValue( policyElement, "version" ) ); return policy; } return null; } /** * Look for the specified policy element, using an XPath traversal of zone, template, and agent nodes * @param zoneId The zoneId to retrieve policy for * @param policySubPath The path of the policy to retrieve, such as "requestPolicy" or "eventPolicy/transmitPolicy" * @param objectName The object type to retrieve policy for * @return */ private Element getPolicyElement( String zoneId, String policySubPath, String objectName ){ if( fConfig != null ){ JXPathContext xpathContext = JXPathContext.newContext( fConfig.getDocument().getDocumentElement() ); xpathContext.setLenient( true ); // Look first, for policy located under the particular zone node Pointer currentPointer = xpathContext.getPointer( "zone[@id='" + zoneId + "']" ); if( currentPointer != null && currentPointer.getNode() != null ){ Element policyNode = findPolicy(xpathContext, currentPointer, policySubPath, objectName ); if( policyNode != null ){ return policyNode; } // No policy for this object found at the zone level, search for policy under the // template Element zoneNode = (Element)currentPointer.getNode(); String templateId = zoneNode.getAttribute( "template" ); if( templateId != null ){ currentPointer = xpathContext.getPointer( "template[@id='" + templateId + "']" ); policyNode = findPolicy(xpathContext, currentPointer, policySubPath, objectName); if( policyNode != null ){ return policyNode; } } } // Finally, look at the root agent element currentPointer = xpathContext.getContextPointer(); return findPolicy(xpathContext, currentPointer, policySubPath, objectName ); } return null; } /** * Looks for a policy node at the specified contextual location for the specified object. * * <p>If a policy node that contains the object name is not found, a search is also done * for the default policy for all objects, with a special name ('*'). * @param xpathContext The XPath context around the agent configuration XML document * @param currentPointer A pointer to a particular node in the document to start searching from, * such as a <code><zone></code>, <code><template></code>, or <code><agent></code> node. * @param policyPath The subPath, such as "requestPolicy" * @param objectName * @return */ private Element findPolicy(JXPathContext xpathContext, Pointer currentPointer, String policyPath, String objectName) { if( currentPointer != null && currentPointer.getNode() != null ){ String objectPolicyPath="policy/" + policyPath + "/object[contains(@name,'" + objectName + "')]"; JXPathContext zoneContext = xpathContext.getRelativeContext( currentPointer ); Element zonePolicy = (Element)zoneContext.selectSingleNode( objectPolicyPath ); if( zonePolicy != null ){ return zonePolicy; } // Look for default policy for all objects at the zone level zonePolicy = (Element)zoneContext.selectSingleNode( "policy/" + policyPath + "/object[@name='*']" ); if( zonePolicy != null ){ return zonePolicy; } } return null; } }