/** * Centralized behavior instantiation <i>factory</i>: <b>instantiate all behaviors through this * method</b> -- never use <code>new <var>behavior</var>(...)</code>. * * <ul> * <li>remapping of names so can dynamically replace references in old hubs * <li>centralized, correct instantiation and error handling * </ul> * * {@link #restore(ESISNode, Map, Layer)} is called as part of instantiation, serving the place of * arguments to a constructor. Logical names are normalized to all lowercase. */ public static Behavior getInstance( String logicalname, String behaviorclass, ESISNode children, Map<String, Object> attr, Layer layer) { assert logicalname != null && behaviorclass != null /*&& (layer!=null || xxx instanceof Layer)--topmost Layer*/ : "logical=" + logicalname + ", class=" + behaviorclass; if (behaviorclass == null) return null; // if not testing (asserts on), keep on truckin' if (multivalent.Meta.MONITOR /*false*/ && layer != null && layer.getBrowser() != null) { Browser br = layer.getBrowser(); Graphics g = br.getGraphics(); // -- works, but not well if (Behavior.rainbowi_ == Behavior.RAINBOW.length) Behavior.rainbowi_ = 0; if (g != null) { // !Multivalent.standalone_ / embedded in Swing g.setColor(Behavior.RAINBOW[Behavior.rainbowi_++]); g.fillRect(0, 0, 10 /*rainbowi_*/, 10); // g.drawLine(0,10, 10,0); } /* g.setColor(Color.WHITE); g.fillRect(250,y_, 600,20); g.setColor(Color.BLACK); rfont_.drawString(g, logicalname+" / "+behaviorclass, 300, y_+15); y_ += 20; if (y_>20*10) y_ = 0; // set to 600 to conver page, but can only take in 10 lines at a time */ } // long start = System.currentTimeMillis(); // String oname = logicalname; logicalname = logicalname.toLowerCase(); // if (!(oname.equals(logicalname))) System.out.println("uppercase logical: "+oname); // warn of // this inefficiency Multivalent v = Multivalent.getInstance(); String bname = v.remapBehavior(behaviorclass); Logger log = getLogger(); // getLogger().finest((/*"getInstance "+logicalname+"/"+behaviorclass+"=>"+bname); if (Behavior.deadbe__.get(bname) == null) try { ClassLoader cl = /*v.getJARsClassLoader();*/ v.getClass().getClassLoader(); // assert cl == Behavior.class.getClassLoader(); // true now with new bootstrapping Object bc = Class.forName(bname, true, cl).newInstance(); Behavior be = (Behavior) bc; // be.setName(logicalname); // can't save uppercase be.name_ = logicalname; // be.name_ = (logicalname!=null? logicalname.toLowerCase(): null); be.classname_ = behaviorclass; // System.out.println(bname); // see save() -- this still ok // if (attr==null) {} else if (attr.get(ATTR_BEHAVIOR)!=null) { if (attr.size()==1) // attr=null; else attr.remove(ATTR_BEHAVIOR); } /* long time = System.currentTimeMillis() - start; if (false && g!=null/* && time > 0L* /) { g.drawString(Long.toString(time), 250,15); try { Thread.currentThread().sleep(2000L); } catch (Exception e) {} } */ be.restore( children, attr, layer); // after added to layer, so can climb around and find things during restore // log.finest("created "+bname); // assert layer!=null || be instanceof Layer; // => temporary use of behavior that don't // want to make logical part of document return be; } catch (ClassNotFoundException e) { log.warning("couldn't find behavior " + bname + " -- ignored"); } catch (ClassCastException e) { log.severe( "class " + bname + " is not a behavior (does not subclass from Behavior) -- ignored"); } catch (InstantiationException e) { log.severe("couldn't instantiate " + bname + " -- is it abstract?"); } catch (IllegalAccessException e) { log.severe(bname + ": " + e + " -- perhaps class or constructor needs to be public"); } catch (Exception e) { e.printStackTrace(); log.severe("unanticipated error while restoring " + logicalname + "/" + bname + ": " + e); } // error fall through Behavior.deadbe__.put(bname, bname); return null; }
/** Convenience method to fetch Browser from Layer. */ public Browser getBrowser() { Layer l = getLayer(); return l != null ? l.getBrowser() : null; }