// // Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s). // All rights reserved. // package openadk.library.impl; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.List; import java.util.StringTokenizer; import openadk.library.*; import openadk.library.common.XMLData; import openadk.library.common.YesNo; import openadk.library.impl.ISIFPrimitives; import openadk.library.infra.*; import openadk.library.services.ServiceRequestInfo; import openadk.util.ADKStringUtils; import org.xml.sax.SAXException; /** * Default implementation of the ISIFPrimitives interface. * * */ public class SIFPrimitives implements ISIFPrimitives { /** * SIF_Register */ public SIF_Ack sifRegister( Zone zone ) throws ADKException { ZoneImpl adkZone = ( ZoneImpl )zone; AgentProperties props = zone.getProperties(); SIFVersion effectiveZISVersion = adkZone.getHighestEffectiveZISVersion(); SIF_Register msg = new SIF_Register( effectiveZISVersion ); msg.setSIF_MaxBufferSize( props.getMaxBufferSize() ); msg.setSIF_Mode( props.getMessagingMode() == AgentMessagingMode.PULL ? "Pull" : "Push" ); // Set the agent's name and version Agent agent = zone.getAgent(); msg.setSIF_Name( agent.getName() ); String vendor = props.getAgentVendor(); if( vendor != null ){ msg.setSIF_NodeVendor( vendor ); } String version = props.getAgentVersion(); if( version != null ){ msg.setSIF_NodeVersion( version ); } SIF_Application applicationInfo = new SIF_Application(); String appName = props.getApplicationName(); if( appName != null ){ applicationInfo.setSIF_Product( appName ); } String appVersion = props.getApplicationVersion(); if( appVersion != null ){ applicationInfo.setSIF_Version( appVersion ); } String appVendor = props.getApplicationVendor(); if( appVendor != null ){ applicationInfo.setSIF_Vendor( appVendor ); } if( applicationInfo.getFieldCount() > 0 ){ // All three fields under SIF_Application are required by the // SIF_Specification. Determine if any are missing. If so, // create the field with an empty value if( applicationInfo.getSIF_Product() == null ){ applicationInfo.setSIF_Product( "" ); } if( applicationInfo.getSIF_Version() == null ){ applicationInfo.setSIF_Version( "" ); } if( applicationInfo.getSIF_Vendor() == null ){ applicationInfo.setSIF_Vendor( "" ); } msg.setSIF_Application( applicationInfo ); } String propVal = props.getAgentIconURL(); if( propVal != null ){ msg.setSIF_Icon( propVal ); } // // SIF_Version handling: // // * If the "adk.provisioning.zisVersion" property is set to > SIF 1.1 // (the default), use SIF 1.1+ registration where multiple SIF_Version // elements are included in the SIF_Register message. Otherwise use // SIF 1.0 registration where only a single SIF_Version is included in // the SIF_Register message. // // For SIF 1.1 registrations: // // * If the "adk.sifRegister.sifVersions" System property is set, // enumerate its comma-delimited list of SIF_Version values and use // those instead of building a list. This is primarily used for // testing wildcards (which the ADK doesn't normally use) or when an // agent wants to connect to a ZIS where wildcarding works better for // some reason. // // * Otherwise, build a list of SIF_Versions: Set the first SIF_Version // element to the version initialized by the ADK, then add a SIF_Version // element for each additional version of SIF supported by the ADK // String forced = zone.getProperties().getOverrideSifVersions(); if( forced != null && forced.trim().length() > 0 ) { ((ZoneImpl)zone).log.debug("Using custom SIF_Register/SIF_Version: " + forced ); StringTokenizer tok = new StringTokenizer( forced, "," ); while( tok.hasMoreTokens() ) { msg.addSIF_Version( new SIF_Version( tok.nextToken().trim() ) ); } } else { SIFVersion zisVer = SIFVersion.parse( zone.getProperties().getZisVersion() ); if( zisVer.compareTo( SIFVersion.SIF11 ) >= 0 ) { // Add the ADK version first. This is the "default" // agent version, which has special meaning to the // ZIS msg.addSIF_Version( new SIF_Version( effectiveZISVersion ) ); if( true ) { // TT 2007 // If the ADK Version is set to 1.1 or 1.5r1, only send those two // versions in the SIF_Register message. The downside to this is // that we can't connect to a 2.0 ZIS using SIF 1.5r1 and still // receive 2.0 events. However, this seems to be the best approach // because it ensures greater compatibility with older ZIS's that will // otherwise fail if they get a 2.0 version in the SIF_Register message SIFVersion[] supported = ADK.getSupportedSIFVersions(); for( int i = 0; i < supported.length; i++ ) { // Exclude the version added above if( supported[i].compareTo( effectiveZISVersion ) < 0 ) { msg.addSIF_Version( new SIF_Version( supported[i] ) ); } } } else { // NOTE: Decided not to do this because the ADK does not currently // support ".*" XML parsing. if( ADK.getSIFVersion().compareTo( SIFVersion.SIF20 ) >= 0 ) { msg.addSIF_Version( new SIF_Version( "2.*" ) ); } msg.addSIF_Version( new SIF_Version( "1.*" ) ); } } else { msg.addSIF_Version( new SIF_Version( ADK.getSIFVersion() ) ); } } // // Set the SIF_Protocol object as supplied by the Transport. Depending // on the transport protocol and the messaging mode employed by the // zone we may or may not get a SIF_Protocol object back // SIF_Protocol po = ((ZoneImpl)zone).getProtocolHandler().makeSIF_Protocol(zone, effectiveZISVersion ); if( po != null ) { /* // TODO: This not currently supported by the 1.0r1 or 1.0r2 DTDs; message won't // pass validation if this is included. Investigate passing parameters on // the URL instead of using the <SIF_Property> element to notify SIFWorks // that an ADK-based agent is connecting. po.setSIF_Property( new SIF_Property( "SIFWorks ADK", ADK.getADKVersion() ) ); */ msg.setSIF_Protocol(po); } return adkZone.getFDispatcher().send(msg); } /** * SIF_Unregister */ public SIF_Ack sifUnregister( Zone zone ) throws ADKException { ZoneImpl adkZone = ( ZoneImpl )zone; SIFVersion effectiveZISVersion = adkZone.getHighestEffectiveZISVersion(); SIFMessagePayload message = new SIF_Unregister( effectiveZISVersion ); return adkZone.getFDispatcher().send( message ); } /** * SIF_Subscribe */ public SIF_Ack sifSubscribe( Zone zone, String[] objectType ) throws ADKException { ZoneImpl adkZone = ( ZoneImpl )zone; SIF_Subscribe msg = new SIF_Subscribe( adkZone.getHighestEffectiveZISVersion() ); for( int i = 0; i < objectType.length; i++ ) { SIF_Object obj = new SIF_Object(); obj.setObjectName( objectType[i] ); msg.addSIF_Object(obj); } return adkZone.getFDispatcher().send(msg); } /** * SIF_Unsubscribe */ public SIF_Ack sifUnsubscribe( Zone zone, String[] objectType ) throws ADKException { ZoneImpl adkZone = ( ZoneImpl )zone; SIF_Unsubscribe msg = new SIF_Unsubscribe( adkZone.getHighestEffectiveZISVersion() ); for( int i = 0; i < objectType.length; i++ ) { SIF_Object obj = new SIF_Object(); obj.setObjectName( objectType[i] ); msg.addSIF_Object(obj); } return adkZone.getFDispatcher().send(msg); } /** * SIF_Provide */ public SIF_Ack sifProvide( Zone zone, String[] objectType ) throws ADKException { ZoneImpl adkZone = ( ZoneImpl )zone; SIF_Provide msg = new SIF_Provide( adkZone.getHighestEffectiveZISVersion() ); for( int i = 0; i < objectType.length; i++ ) { SIF_Object obj = new SIF_Object(); obj.setObjectName( objectType[i] ); msg.addSIF_Object(obj); } return adkZone.getFDispatcher().send(msg); } /** * SIF_Unprovide */ public SIF_Ack sifUnprovide( Zone zone, String[] objectType ) throws ADKException { ZoneImpl adkZone = ( ZoneImpl )zone; SIF_Unprovide msg = new SIF_Unprovide( adkZone.getHighestEffectiveZISVersion() ); for( int i = 0; i < objectType.length; i++ ) { SIF_Object obj = new SIF_Object(); obj.setObjectName( objectType[i] ); msg.addSIF_Object(obj); } return adkZone.getFDispatcher().send(msg); } /** * SIF_Ping */ public SIF_Ack sifPing( Zone zone ) throws ADKException { return sifSystemControl( new SIF_Ping(), (ZoneImpl)zone ); } /** * SIF_ZoneStatus */ public SIF_Ack sifZoneStatus( Zone zone ) throws ADKException { return sifSystemControl( new SIF_GetZoneStatus(), (ZoneImpl)zone ); } /** * SIF_Sleep */ public SIF_Ack sifSleep( Zone zone ) throws ADKException { return sifSystemControl( new SIF_Sleep(), (ZoneImpl)zone ); } /** * SIF_GetAgentACL */ public SIF_Ack sifGetAgentACL(Zone zone) throws ADKException { return sifSystemControl( new SIF_GetAgentACL(), (ZoneImpl)zone ); } /** * SIF_Wakeup */ public SIF_Ack sifWakeup( Zone zone ) throws ADKException { return sifSystemControl( new SIF_Wakeup(), (ZoneImpl)zone ); } private SIF_Ack sifSystemControl( SIFElement command, ZoneImpl zone ) throws ADKException { SIF_SystemControl msg = new SIF_SystemControl( zone.getHighestEffectiveZISVersion() ); SIF_SystemControlData cmd = new SIF_SystemControlData(); cmd.addChild( command ); msg.setSIF_SystemControlData(cmd); return zone.getFDispatcher().send(msg); } /** * Sends a SIF_Event * @param zone The zone to send the event to */ public SIF_Ack sifEvent( Zone zone, Event event, String destinationId, String sifMsgId ) throws ADKException { if( event.getData() == null || event.getData().available() == false ) throw new ADKException( "The event has no SIFDataObjects", zone ); SIF_ObjectData od = new SIF_ObjectData(); // Fill out the SIF_ObjectData DataObjectInputStream inStr = event.getData(); SIFDataObject data = inStr.readDataObject(); SIFVersion msgVersion = data.effectiveSIFVersion(); SIF_EventObject eo = new SIF_EventObject(); od.setSIF_EventObject( eo ); eo.setAction( event.getActionString() ); eo.setObjectName( data.getElementDef().tag( msgVersion ) ); // Create the SIF_Event object SIF_Event msg = new SIF_Event( msgVersion ); msg.setSIF_ObjectData(od); SIF_Header msgHdr = msg.getHeader(); // Assign SIF_DestinationId if applicable if( destinationId != null ) { msgHdr.setSIF_DestinationId(destinationId); } while( data != null ) { eo.attach( data ); data = inStr.readDataObject(); } if( sifMsgId != null ) { msgHdr.setSIF_MsgId(sifMsgId); } SIFContext[] contexts = event.getContexts(); if( contexts == null ){ contexts = new SIFContext[] { SIFContext.DEFAULT }; } SIF_Contexts msgContexts = new SIF_Contexts(); for( SIFContext context : contexts ){ msgContexts.addSIF_Context( context.getName() ); } msgHdr.setSIF_Contexts( msgContexts ); return ((ZoneImpl)zone).getFDispatcher().send(msg); } /** * SIF_Request */ public SIF_Ack sifRequest( Zone zone, Query query, String destinationId, String sifMsgId ) throws ADKException { // Send SIF_Request... SIF_Request msg = new SIF_Request(); // Find the maxmimum requested version and set the version of the message to lower // if the version is currently higher than the highest requested version. // In other words, if the ADK is initialized to 2.0, but the highest requested version // is 1.5r1, set the message version to 1.5r1 SIFVersion highestRequestVersion = SIFVersion.SIF11; if( query.getObjectType() == InfraDTD.SIF_ZONESTATUS ){ // This query will be satisfied by the ZIS. Use the ZIS compatibility // version, which returns the highest version supported by the ZIS // (Default to ADK.getSIFVersion() if not specified in the config) highestRequestVersion = ( (ZoneImpl)zone).getHighestEffectiveZISVersion(); msg.addSIF_Version( new SIF_Version( highestRequestVersion ) ); } else { SIFVersion[] requestVersions = query.getSIFVersions(); if( requestVersions.length > 0 ){ // If the Query has one or more SIFVersions set, use them, // and also add [major].* for( SIFVersion version : requestVersions ){ msg.addSIF_Version( new SIF_Version( version ) ); if( version.compareTo( highestRequestVersion ) > 0 ){ highestRequestVersion = version; } } } else { highestRequestVersion = ADK.getSIFVersion(); if( highestRequestVersion.getMajor() == 1 ){ msg.addSIF_Version( new SIF_Version( highestRequestVersion ) ); } else { // 2.0 and greater, request all data using // [major].*, with 2.0r1 as the message version // This allows for maximum compatibility will all 2.x providers msg.addSIF_Version( new SIF_Version( String.valueOf( highestRequestVersion.getMajor() ) + ".*" )); // Version change also made when Message read in SIFVersion earliest = SIFVersion.getEarliest( highestRequestVersion.getMajor() ); if( earliest.compareTo( query.getObjectType().getEarliestVersion()) < 0 ){ // This object type is new since the release of SIF. Use the minimum version // The object appeared in as the message version. msg.setSIFVersion( query.getObjectType().getEarliestVersion() ); } else { msg.setSIFVersion( earliest ); } } } } AgentProperties zoneProperties = zone.getProperties(); String overrideRequestVersion = zoneProperties.getOverrideSifMessageVersionForSifRequests(); if (overrideRequestVersion != null && overrideRequestVersion.length() > 0) { //There is a property in Agent.cfg that can be used to override the message version from the //default of 2.0r1. This is needed to pass the test harness for 2.3. msg.setSIFVersion(SIFVersion.parse(overrideRequestVersion)); } else if( msg.getSIFVersion().compareTo( highestRequestVersion ) > 0 ){ // The current version of the SIF_Message is higher than the highest // requested version. Back the version number of message down to match msg.setSIFVersion( highestRequestVersion ); } msg.setSIF_MaxBufferSize( zone.getProperties().getMaxBufferSize() ); SIF_Query sifQ = createSIF_Query( query, highestRequestVersion, zone ); msg.setSIF_Query( sifQ ); SIF_Header msgHeader = msg.getHeader(); if( destinationId != null ) { msgHeader.setSIF_DestinationId(destinationId); } if( sifMsgId != null ) { msgHeader.setSIF_MsgId(sifMsgId); } // Set the SIF_Context msgHeader.setSIF_Contexts( new SIF_Contexts( new SIF_Context( query.getSIFContext().getName() ) ) ); return ((ZoneImpl)zone).getFDispatcher().send(msg); } public SIF_Ack sifCancelRequests(ZoneImpl zone, String destinationId, String[] sif_MsgIds) throws ADKException { // Send CancelRequests... SIF_CancelRequests msg = new SIF_CancelRequests(); msg.setSIF_NotificationType(SIF_NotificationType.STANDARD); SIF_RequestMsgIds sif_RequestMsgIds = new SIF_RequestMsgIds(); for (int i=0; i< sif_MsgIds.length; ++i) { SIF_RequestMsgId sif_RequestMsgId = new SIF_RequestMsgId(); sif_RequestMsgId.setValue(sif_MsgIds[i]); sif_RequestMsgIds.add(sif_RequestMsgId); } msg.setSIF_RequestMsgIds(sif_RequestMsgIds); return sifSystemControl( msg, (ZoneImpl)zone ); } /** * Creates a SIF_Query element from the specified ADK query object using * zone-specific querying rules * @param query The Query to convert to a SIF_Query * @param zone The Zone to retrieve query settings from, or null * @return a SIF_Query instance */ public static SIF_Query createSIF_Query( Query query, Zone zone ) { boolean allowFieldRestrictions = query.hasFieldRestrictions(); if( allowFieldRestrictions && zone !=null ) { allowFieldRestrictions = !zone.getProperties().getNoRequestIndividualElements(); } return createSIF_Query( query, query.getEffectiveVersion(), allowFieldRestrictions ); } /** * Creates a SIF_Query element from the specified ADK query object using * zone-specific querying rules * @param query The Query to convert to a SIF_Query * @param version The version of SIF to render the SIF_Query xml in * @param zone The Zone to retrieve query settings from, or null * @return a SIF_Query instance */ public static SIF_Query createSIF_Query( Query query, SIFVersion version, Zone zone ) { boolean allowFieldRestrictions = query.hasFieldRestrictions(); if( allowFieldRestrictions && zone !=null ) { allowFieldRestrictions = !zone.getProperties().getNoRequestIndividualElements(); } return createSIF_Query( query, version, allowFieldRestrictions ); } /** * Creates a SIF_Query element from the specified ADK query object using * the specified version of SIF * @param query The Query to convert to a SIF_Query * @param version The version of SIF to render the SIF_Query xml in * @param allowFieldRestrictions True if the field restrictions in the query should be rendered * @return a SIF_Query object */ public static SIF_Query createSIF_Query( Query query, SIFVersion version, boolean allowFieldRestrictions ) { SIF_QueryObject sqo = new SIF_QueryObject(query.getObjectType().tag( version )); SIF_Query sifQ = new SIF_Query( sqo ); if( query.hasConditions() ) { sifQ.setSIF_ConditionGroup( createConditionGroup( query, version ) ); } if( allowFieldRestrictions && query.hasFieldRestrictions() ) { for( ElementRef elementRef : query.getFieldRestrictionRefs()){ String path = null; ElementDef field = elementRef.getField(); if( field != null ) { if( !field.isSupported( version ) ) { continue; } path = field.getSQPPath( version ); } if( path == null ) { path = elementRef.getXPath(); } if( path != null ) { path = ADK.DTD().translateSQP( query.getObjectType(), path, version ); sqo.addSIF_Element(new SIF_Element( path )); } } } return sifQ; } private static SIF_ConditionGroup createConditionGroup( Query query, SIFVersion effectiveVersion ) { // Create the hierarchy SIF_ConditionGroup // > SIF_Conditons // > SIF_Condition // From // ConditionGroup // > [ConditionGroup (Optional)] // > Condition SIF_ConditionGroup returnGroup = new SIF_ConditionGroup(); returnGroup.setType( ConditionType.NONE ); ConditionGroup cg = query.getRootConditionGroup(); ConditionGroup[] groups = cg.getGroups(); if( groups != null && groups.length > 0 ) { // // There's one or more ConditionGroups... // These get translated to SIF_Conditions elements // if( cg.getOperator() == GroupOperators.OR ){ returnGroup.setType( ConditionType.OR ); } else if( cg.getOperator() == GroupOperators.AND ){ returnGroup.setType( ConditionType.AND ); } for( ConditionGroup group : groups ) { returnGroup.addSIF_Conditions( createConditions( query, group, effectiveVersion ) ); } } else { // // There are no SIF_Conditions groups, so build one... // returnGroup.addSIF_Conditions( createConditions( query, cg, effectiveVersion ) ); } return returnGroup; } private static SIF_Conditions createConditions( Query query, ConditionGroup group, SIFVersion effectiveVersion ) { ConditionType typ = ConditionType.NONE; if( group.getOperator() == GroupOperators.AND ){ typ = ConditionType.AND; } else if( group.getOperator() == GroupOperators.OR ){ typ = ConditionType.OR; } Condition[] conditions = group.getConditions(); SIF_Conditions conds = new SIF_Conditions( conditions.length > 1 ? typ : ConditionType.NONE ); for( Condition c : conditions ) { conds.addSIF_Condition( c.getXPath( query, effectiveVersion ), c.getOperator().getSIFValue(), c.getValue() ); } return conds; } /* (non-Javadoc) * @see openadk.library.impl.ISIFPrimitives#sifProvision(openadk.library.Zone, openadk.library.infra.SIF_Provision) */ public SIF_Ack sifProvision( Zone zone, SIF_ProvideObjects providedObjects, SIF_SubscribeObjects subscribeObjects, SIF_PublishAddObjects publishAddObjects, SIF_PublishChangeObjects publishChangeObjects, SIF_PublishDeleteObjects publishDeleteObjects, SIF_RequestObjects requestObjects, SIF_RespondObjects respondObjects ) throws ADKException { SIF_Provision msg = new SIF_Provision( ((ZoneImpl)zone).getHighestEffectiveZISVersion() ); if( providedObjects != null ){ msg.setSIF_ProvideObjects( providedObjects ); } if( publishAddObjects != null ){ msg.setSIF_PublishAddObjects( publishAddObjects ); } if( publishChangeObjects != null ){ msg.setSIF_PublishChangeObjects( publishChangeObjects ); } if( publishDeleteObjects != null ){ msg.setSIF_PublishDeleteObjects( publishDeleteObjects ); } if( subscribeObjects != null ){ msg.setSIF_SubscribeObjects( subscribeObjects ); } if( requestObjects != null ){ msg.setSIF_RequestObjects( requestObjects ); } if( respondObjects != null ){ msg.setSIF_RespondObjects( respondObjects ); } return ((ZoneImpl)zone).getFDispatcher().send( msg ); } /** * Attempts to parse attributes out of the source message enough to make a valid * SIF_Ack with a SIF_Error. This is useful in conditions where the source message cannot * be parsed by the ADK * * @param sourceMessage The original message as a string * @param error The error to place in the SIF_Ack/SIF_Error * @param zone The zone associated with this message * @return * @throws ADKMessagingException */ public static SIF_Ack ackError(String sourceMessage, SIFException error, ZoneImpl zone ) { SIFMessageInfo parsed = null; try { StringReader reader = new StringReader( sourceMessage ); parsed = SIFMessageInfo.parse(reader, false, zone ); reader.close(); } catch (IOException ioe ){ zone.getLog().error( ioe, ioe ); } catch (ADKMessagingException e) { zone.getLog().error( e, e ); } SIF_Ack errorAck = new SIF_Ack( zone.getHighestEffectiveZISVersion() ); if( parsed != null ){ // Set SIFVersion, OriginalSourceId, and OriginalMsgId; if( parsed.getSIFVersion() != null ){ errorAck.setSIFVersion( parsed.getSIFVersion() ); } errorAck.setSIF_OriginalMsgId( parsed.getAttribute( "SIF_MsgId" ) ); errorAck.setSIF_OriginalSourceId( parsed.getAttribute( "SIF_SourceId" ) ); } SetRequiredAckValues( errorAck ); SIF_Error newErr = new SIF_Error(); newErr.setSIF_Category( error.getSIFErrorCategory() ); newErr.setSIF_Code( error.getErrorCode() ); newErr.setSIF_Desc( error.getErrorDesc() ); newErr.setSIF_ExtendedDesc( error.getErrorExtDesc() ); errorAck.setSIF_Error( newErr ); return errorAck; } /** * If the SIF_OriginalMsgID or SIF_OriginalSourceId are not set, * process according to Infrastructure resolution #157 * @param errorAck */ public static void SetRequiredAckValues( SIF_Ack errorAck ) { // Return a SIF_Ack with a blank SIF_OriginalSourceId and // SIF_OriginalMsgId per SIFInfra resolution #157 // Also See 4.1.2.1 SIF_Message processing if( errorAck.getField( InfraDTD.SIF_ACK_SIF_ORIGINALMSGID ) == null ){ // Set SIF_OriginalMsgId to xsi:nill errorAck.setField( InfraDTD.SIF_ACK_SIF_ORIGINALMSGID, new SIFString( null ) ); } if( errorAck.getField( InfraDTD.SIF_ACK_SIF_ORIGINALSOURCEID ) == null ){ // Set SIF_OriginalSource to an empty string errorAck.setSIF_OriginalSourceId( "" ); } } /** * JEN - new Service Request * @see openadk.library.impl.ISIFPrimitives#sifServiceRequest(openadk.library.Zone, openadk.library.services.ServiceRequestInfo, openadk.library.SIFElement) */ public SIF_Ack sifServiceRequest(Zone zone, ServiceRequestInfo requestInfo, SIFElement payload) throws ADKException { // Send SIF_ServiceInput... SIF_ServiceInput msg = new SIF_ServiceInput(); msg.setSIF_Service(requestInfo.getServiceName()); msg.setSIF_Operation(requestInfo.getMethodName()); msg.setSIF_ServiceMsgId(requestInfo.getSIFServiceMsgId()); msg.setSIFVersion(SIFVersion.LATEST); // todo fix // todo implement packetization msg.setSIF_PacketNumber(1); msg.setSIF_MorePackets(YesNo.NO); // Find the maxmimum requested version and set the version of the message to lower // if the version is currently higher than the highest requested version. // In other words, if the ADK is initialized to 2.0, but the highest requested version // is 1.5r1, set the message version to 1.5r1 // SIFVersion highestRequestVersion = SIFVersion.SIF11; SIFVersion highestRequestVersion = SIFVersion.LATEST; /* if( query.getObjectType() == InfraDTD.SIF_ZONESTATUS ){ // This query will be satisfied by the ZIS. Use the ZIS compatibility // version, which returns the highest version supported by the ZIS // (Default to ADK.getSIFVersion() if not specified in the config) highestRequestVersion = ( (ZoneImpl)zone).getHighestEffectiveZISVersion(); msg.addSIF_Version( new SIF_Version( highestRequestVersion ) ); } else { SIFVersion[] requestVersions = query.getSIFVersions(); if( requestVersions.length > 0 ){ // If the Query has one or more SIFVersions set, use them, // and also add [major].* for( SIFVersion version : requestVersions ){ msg.addSIF_Version( new SIF_Version( version ) ); if( version.compareTo( highestRequestVersion ) > 0 ){ highestRequestVersion = version; } } } else { highestRequestVersion = ADK.getSIFVersion(); if( highestRequestVersion.getMajor() == 1 ){ msg.addSIF_Version( new SIF_Version( highestRequestVersion ) ); } else { // 2.0 and greater, request all data using // [major].*, with 2.0r1 as the message version // This allows for maximum compatibility will all 2.x providers msg.addSIF_Version( new SIF_Version( String.valueOf( highestRequestVersion.getMajor() ) + ".*" )); msg.setSIFVersion( SIFVersion.getEarliest( highestRequestVersion.getMajor() ) ); } } } */ if( msg.getSIFVersion().compareTo( highestRequestVersion ) > 0 ){ // The current version of the SIF_Message is higher than the highest // requested version. Back the version number of message down to match msg.setSIFVersion( highestRequestVersion ); } msg.setSIF_MaxBufferSize( zone.getProperties().getMaxBufferSize() ); /* StringWriter sw = new StringWriter(); SIFWriter writer = new SIFWriter(sw); writer.suppressNamespace(true); writer.write(payload); writer.flush(); writer.close(); String xml = sw.toString(); XMLData xmlData = new XMLData(); try { xmlData.setXML(loadXMLFrom(xml)); } catch (Exception e) { } */ // msg.setSIF_Body(xmlData); SIF_Body sifBody = new SIF_Body(); sifBody.addChild(payload); msg.setSIF_Body(sifBody); SIF_Header msgHeader = msg.getHeader(); if( requestInfo.getDestinationId() != null ) { msgHeader.setSIF_DestinationId(requestInfo.getDestinationId()); } // Set the SIF_Context /* msgHeader.setSIF_Contexts( new SIF_Contexts( new SIF_Context( query.getSIFContext().getName() ) ) ); */ return ((ZoneImpl)zone).getFDispatcher().send(msg); } private static org.w3c.dom.Document loadXMLFrom(String xml) throws org.xml.sax.SAXException, java.io.IOException { return loadXMLFrom(new java.io.ByteArrayInputStream(xml.getBytes())); } private static org.w3c.dom.Document loadXMLFrom(java.io.InputStream is) throws org.xml.sax.SAXException, java.io.IOException { javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); javax.xml.parsers.DocumentBuilder builder = null; try { builder = factory.newDocumentBuilder(); } catch (javax.xml.parsers.ParserConfigurationException ex) { } org.w3c.dom.Document doc = builder.parse(is); is.close(); return doc; } public SIF_Ack sifServiceEvent(Zone zone, ServiceEvent event, String destinationId) throws ADKException { if( event.getData() == null || event.getData().available() == false ) throw new ADKException( "The event has no SIFDataObjects", zone ); // Create the SIF_ServiceNotify object DataObjectInputStream inStr = event.getData(); SIFDataObject data = inStr.readDataObject(); SIFVersion msgVersion = data.effectiveSIFVersion(); SIF_ServiceNotify msg = new SIF_ServiceNotify( msgVersion ); msg.setSIFVersion(SIFVersion.LATEST); // todo fix msg.setSIF_Service(event.getService()); msg.setSIF_Operation(event.getOperation()); msg.setSIF_ServiceMsgId(event.getServiceMsgId()); msg.setSIF_PacketNumber(1); // todo fix msg.setSIF_MorePackets(YesNo.NO); // Body SIF_Body sifBody = new SIF_Body(); while( data != null ) { sifBody.addChild(data); data = inStr.readDataObject(); } msg.setSIF_Body(sifBody); // Header SIF_Header msgHdr = msg.getHeader(); // Assign SIF_DestinationId if applicable if( destinationId != null ) { msgHdr.setSIF_DestinationId(destinationId); } /* if( sifMsgId != null ) { msgHdr.setSIF_MsgId(sifMsgId); } */ SIFContext[] contexts = event.getContexts(); if( contexts == null ){ contexts = new SIFContext[] { SIFContext.DEFAULT }; } SIF_Contexts msgContexts = new SIF_Contexts(); for (SIFContext context : contexts) { msgContexts.addSIF_Context( context.getName() ); } msgHdr.setSIF_Contexts( msgContexts ); return ((ZoneImpl)zone).getFDispatcher().send(msg); } }