001/* 002 * Copyright (c) 2003-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2015-08-24 22:45:41 +0000 (Mon, 24 Aug 2015) $' 007 * '$Revision: 33631 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.objectmanager.cache; 031 032import java.io.ByteArrayInputStream; 033import java.io.ByteArrayOutputStream; 034import java.io.Externalizable; 035import java.io.IOException; 036import java.io.InputStream; 037import java.io.ObjectInput; 038import java.io.ObjectOutput; 039import java.io.StringReader; 040import java.util.Map; 041 042import javax.xml.parsers.DocumentBuilder; 043import javax.xml.parsers.DocumentBuilderFactory; 044 045import org.apache.commons.logging.Log; 046import org.apache.commons.logging.LogFactory; 047import org.kepler.moml.KeplerActorMetadata; 048import org.kepler.moml.KeplerMetadataExtractor; 049import org.kepler.moml.NamedObjId; 050import org.kepler.objectmanager.ActorMetadata; 051import org.kepler.objectmanager.lsid.KeplerLSID; 052import org.w3c.dom.Document; 053import org.w3c.dom.NamedNodeMap; 054import org.w3c.dom.Node; 055import org.w3c.dom.NodeList; 056import org.xml.sax.EntityResolver; 057import org.xml.sax.InputSource; 058import org.xml.sax.SAXException; 059 060import ptolemy.moml.MoMLParser; 061import ptolemy.util.MessageHandler; 062 063/** 064 * Class that represents an object in the ObjectCache. This class should be 065 * extended by each type of object that wants to control its own lifecycle 066 * events and serialization events. 067 * 068 *@author berkley 069 *@created September 7, 2007 070 */ 071 072/** 073 * Modified by Dan Higgins, Aug 9, 2007 to avoid instantiating all the actors 074 * when the ActorCacheObject is created. This is done be avoiding creating the 075 * ActorMetadata object and using the MoML parser. Instead a DOM parser is used 076 * to pull out just a few of parameters in the kar files MoML description of the 077 * actor, and the xml saved with the ActorCacheObject is exactly that in the kar 078 * file. 079 * 080 *@author berkley 081 *@created September 7, 2007 082 */ 083public class ActorCacheObject extends CacheObject implements Externalizable { 084 085 private static final Log log = LogFactory.getLog(ActorCacheObject.class 086 .getName()); 087 private static final boolean isDebugging = log.isDebugEnabled(); 088 089 /** 090 * 091 */ 092 private ActorMetadata _actor = null; 093 094 /** 095 * 096 */ 097 private String _actorString; 098 099 /** 100 * 101 */ 102 private String _className; 103 104 /** 105 * 106 */ 107 private String _rootname; 108 109 /** 110 * Constructor for the ActorCacheObject object 111 */ 112 public ActorCacheObject() { 113 super(); 114 _actor = null; 115 } 116 117 /** 118 * construct a new CacheObject 119 * 120 *@param name 121 * Description of the Parameter 122 *@param lsid 123 * Description of the Parameter 124 */ 125 public ActorCacheObject(String name, KeplerLSID lsid) { 126 super(name, lsid); 127 if (isDebugging) 128 log.debug("ActorCacheObject(" + name + "," + lsid + ")"); 129 } 130 131 /** 132 * create an ActorCacheObject from a stream 133 * 134 * @param actorStream 135 * the stream of the actor moml 136 * @exception CacheException 137 * Description of the Exception 138 */ 139 public ActorCacheObject(InputStream actorStream) throws CacheException { 140 super(); 141 if (isDebugging) 142 log.debug("ActorCacheObject(" + actorStream.getClass().getName() 143 + ")"); 144 145 KeplerActorMetadata kam = null; 146 try { 147 kam = KeplerMetadataExtractor 148 .extractActorMetadata(actorStream); 149 } catch (Exception e1) { 150 e1.printStackTrace(); 151 } 152 153 if (kam != null) { 154 _actorString = kam.getActorString(); 155 this.setName( kam.getName() ); 156 this.setLSID( kam.getLsid() ); 157 _className = kam.getClassName(); 158 _rootname = kam.getRootName(); 159 setSemanticTypes( kam.getSemanticTypes() ); 160 161 Map<String,String> attributes = kam.getAttributes(); 162 if (attributes != null) { 163 for (String attributeName : attributes.keySet()) { 164 String attributeValue = attributes.get(attributeName); 165 this.addAttribute(attributeName, attributeValue); 166 167 } 168 } 169 } 170 } 171 172 /** 173 * this returns an ActorMetadata object. It will need to be casted to be 174 * used 175 * 176 *@return The object value 177 */ 178 public Object getObject() { 179 if (isDebugging) 180 log.debug("getObject()"); 181 return getMetadata(); 182 } 183 184 /** 185 * serialize this class 186 * 187 *@param out 188 * Description of the Parameter 189 *@exception IOException 190 * Description of the Exception 191 */ 192 public void writeExternal(ObjectOutput out) throws IOException { 193 if (isDebugging) 194 log.debug("writeExternal(" + out.getClass().getName() + ")"); 195 byte[] b = _actorString.getBytes(); 196 out.write(b, 0, b.length); 197 out.flush(); 198 } 199 200 /** 201 * deserialize this class 202 * 203 *@param in 204 * Description of the Parameter 205 *@exception IOException 206 * Description of the Exception 207 *@exception ClassNotFoundException 208 * Description of the Exception 209 */ 210 public void readExternal(ObjectInput in) throws IOException, 211 ClassNotFoundException { 212 if (isDebugging) 213 log.debug("readExternal(" + in.getClass().getName() + ")"); 214 215 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 216 byte[] b = new byte[1024]; 217 int numread = in.read(b, 0, 1024); 218 while (numread != -1) { 219 bos.write(b, 0, numread); 220 numread = in.read(b, 0, 1024); 221 } 222 bos.flush(); 223 _actorString = bos.toString(); 224 try { 225 StringReader strR = new StringReader(_actorString); 226 InputSource xmlIn = new InputSource(strR); 227 DocumentBuilderFactory factory = DocumentBuilderFactory 228 .newInstance(); 229 DocumentBuilder builder = factory.newDocumentBuilder(); 230 builder.setEntityResolver(new EntityResolver() { 231 public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { 232 if (MOML_PUBLIC_ID_1.equals(publicId)) { 233 return new InputSource(MoMLParser.class.getResourceAsStream("MoML_1.dtd")); 234 } 235 else { 236 return null; 237 } 238 } 239 }); 240 Document doc = builder.parse(xmlIn); 241 Node rootNode = doc.getDocumentElement(); 242 _rootname = rootNode.getNodeName(); 243 NamedNodeMap nnm = rootNode.getAttributes(); 244 Node namenode = nnm.getNamedItem("name"); 245 String nameStr = namenode.getNodeValue(); 246 this._name = nameStr; 247 NodeList probNodes = rootNode.getChildNodes(); 248 for (int i = 0; i < probNodes.getLength(); i++) { 249 Node child = probNodes.item(i); 250 if (child.hasAttributes()) { 251 NamedNodeMap childAttrs = child.getAttributes(); 252 Node idNode = childAttrs.getNamedItem("name"); 253 if (idNode != null) { 254 String nameval = idNode.getNodeValue(); 255 if (nameval.equals(NamedObjId.NAME)) { 256 Node idNode1 = childAttrs.getNamedItem("value"); 257 String idval = idNode1.getNodeValue(); 258 this._lsid = new KeplerLSID(idval); 259 } 260 if (nameval.equals("class")) { 261 Node idNode3 = childAttrs.getNamedItem("value"); 262 String classname = idNode3.getNodeValue(); 263 this._className = classname; 264 } 265 if (nameval.startsWith("semanticType")) { 266 Node idNode2 = childAttrs.getNamedItem("value"); 267 String semtype = idNode2.getNodeValue(); 268 _semanticTypes.add(semtype); 269 } 270 } 271 } 272 } 273 } catch (Exception e) { 274 e.printStackTrace(); 275 throw new IOException("Error in ActorCacheObject(ReadExternal): " 276 + e.getMessage()); 277 } 278 } 279 280 /** 281 * Return the ActorMetadata for this actor. 282 * 283 *@return The metadata value 284 */ 285 public ActorMetadata getMetadata() { 286 if (isDebugging) 287 log.debug("getMetadata()"); 288 if (_actor == null) { 289 // added if actor has never been created - DFH 290 try { 291 byte[] bb = _actorString.getBytes(); 292 ByteArrayInputStream bytein = new ByteArrayInputStream(bb); 293 _actor = new ActorMetadata(bytein); 294 } catch (Exception e) { 295 MessageHandler.error("Error parsing actor metadata.", e); 296 } 297 } 298 return _actor; 299 } 300 301 /** 302 * Gets the className attribute of the ActorCacheObject object. 303 * 304 *@return The className value 305 */ 306 public String getClassName() { 307 return _className; 308 } 309 310 /** 311 * Gets the actorString attribute of the ActorCacheObject object. 312 * 313 *@return The actorString value 314 */ 315 public String getActorString() { 316 return _actorString; 317 } 318 319 /** 320 * Gets the rootName attribute of the ActorCacheObject object. 321 * 322 *@return The rootName value 323 */ 324 public String getRootName() { 325 return _rootname; 326 } 327 328 public static String MOML_PUBLIC_ID_1 = "-//UC Berkeley//DTD MoML 1//EN"; 329}