/** * Add a new rule with its style. If the rule selector is just GRAPH, NODE, EDGE or SPRITE, the * default corresponding rules make a copy (or augmentation) of its style. Else if an id or class * is specified the rules are added (or changed/augmented if the id or class was already set) and * their parent is set to the default graph, node, edge or sprite rules. If this is an event rule * (or meta-class rule), its sibling rule (the same rule without the meta-class) is searched and * created if not found and the event rule is added as an alternative to it. * * @param newRule The new rule. */ public void addRule(Rule newRule) { Rule oldRule = null; switch (newRule.selector.getType()) { case ANY: throw new RuntimeException( "The ANY selector should never be used, it is created automatically."); case GRAPH: oldRule = graphRules.addRule(newRule); break; case NODE: oldRule = nodeRules.addRule(newRule); break; case EDGE: oldRule = edgeRules.addRule(newRule); break; case SPRITE: oldRule = spriteRules.addRule(newRule); break; default: throw new RuntimeException("Ho ho ho ?"); } for (StyleSheetListener listener : listeners) listener.styleAdded(oldRule, newRule); }
/** Clear all specific rules and initialise the default rules. The listeners are not changed. */ public void clear() { graphRules.clear(); nodeRules.clear(); edgeRules.clear(); spriteRules.clear(); initRules(); for (StyleSheetListener listener : listeners) listener.styleSheetCleared(); }
// {{{ literalBeanShellReplace() method private static String literalBeanShellReplace(View view, JEditBuffer buffer, CharSequence found) throws Exception { replaceNS.setVariable("buffer", buffer); replaceNS.setVariable("_0", found); Object obj = BeanShell.runCachedBlock(replaceMethod, view, replaceNS); replaceNS.setVariable("_0", null, false); // Not really necessary because it is already cleared in the end of // BeanShell.runCachedBlock() replaceNS.setVariable("buffer", null, false); if (obj == null) return ""; else return obj.toString(); } // }}}
@Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("StyleSheet : {\n"); builder.append(" default styles:\n"); builder.append(defaultRule.toString(1)); builder.append(graphRules.toString(1)); builder.append(nodeRules.toString(1)); builder.append(edgeRules.toString(1)); builder.append(spriteRules.toString(1)); return builder.toString(); }
/** Returns either a class or methods mirror Returns noMirror if there is no match */ protected Mirror getMirror(final String class_) { if (class_ == null) { return noMirror; } // See if we can find an existing mirror final Mirror cachedMirror = mirrors.get(class_); if (cachedMirror != null) { return cachedMirror; } // Perform the lookup (on both class and methods if necessary) for (NameSpace n : namespaces) { String mirrorClass = n.getMirrorClassName(class_); if (mirrorClass == null) { continue; } mirrorClass = mirrorClass.replace('/', '.'); // Attempt class mirror first try { final Class clazz = Class.forName(mirrorClass); final Mirror mirror = new ClassMirror(clazz); mirrors.put(class_, mirror); return mirror; } catch (ClassNotFoundException e) { // NOPMD by xlv } // Attempt methods mirror mirrorClass += '_'; try { final Class clazz = Class.forName(mirrorClass); final Mirror mirror = new MethodsMirror(clazz); mirrors.put(class_, mirror); return mirror; } catch (ClassNotFoundException e) { // NOPMD by xlv } } // No matches in any of the namespaces mirrors.put(class_, noMirror); return noMirror; }
/** * Get the rules that match a given element. * * <p>First a rule for the identifier of the element is looked for. It is looked for in its name * space (nodes for Node element, etc.) If it is not found, the default rule for this kind of * element is used. This rule is pushed at start of the returned array of rules. * * <p>After a rule for the element is found, then the various classes the element pertains to are * looked at and each class rule found is added in order in the returned array. * * @param element The element a rules are searched for. * @return A set of rules matching the element, with the main rule at index 0. */ public ArrayList<Rule> getRulesFor(Element element) { ArrayList<Rule> rules = null; if (element instanceof Graph) { rules = graphRules.getRulesFor(element); } else if (element instanceof Node) { rules = nodeRules.getRulesFor(element); } else if (element instanceof Edge) { rules = edgeRules.getRulesFor(element); } else if (element instanceof GraphicSprite) { rules = spriteRules.getRulesFor(element); } else { rules = new ArrayList<Rule>(); rules.add(defaultRule); } return rules; }
/** * Create the default rules. This method is the place to set defaults for specific element types. * This is here that the edge width is reset to one, since the default width is larger. The * default z index that is different for every class of element is also set here. */ protected void initRules() { defaultRule = new Rule(new Selector(Selector.Type.ANY), null); defaultRule.getStyle().setDefaults(); graphRules.defaultRule = new Rule(new Selector(Selector.Type.GRAPH), defaultRule); nodeRules.defaultRule = new Rule(new Selector(Selector.Type.NODE), defaultRule); edgeRules.defaultRule = new Rule(new Selector(Selector.Type.EDGE), defaultRule); spriteRules.defaultRule = new Rule(new Selector(Selector.Type.SPRITE), defaultRule); graphRules.defaultRule.getStyle().setValue("padding", new Values(Style.Units.PX, 30)); edgeRules.defaultRule.getStyle().setValue("shape", StyleConstants.Shape.LINE); edgeRules.defaultRule.getStyle().setValue("size", new Values(Style.Units.PX, 1)); edgeRules.defaultRule.getStyle().setValue("z-index", new Integer(1)); nodeRules.defaultRule.getStyle().setValue("z-index", new Integer(2)); spriteRules.defaultRule.getStyle().setValue("z-index", new Integer(3)); Colors colors = new Colors(); colors.add(Color.WHITE); graphRules.defaultRule.getStyle().setValue("fill-color", colors); graphRules.defaultRule.getStyle().setValue("stroke-mode", StrokeMode.NONE); for (StyleSheetListener listener : listeners) { listener.styleAdded(defaultRule, defaultRule); listener.styleAdded(graphRules.defaultRule, graphRules.defaultRule); listener.styleAdded(nodeRules.defaultRule, nodeRules.defaultRule); listener.styleAdded(edgeRules.defaultRule, edgeRules.defaultRule); listener.styleAdded(spriteRules.defaultRule, spriteRules.defaultRule); } // for( StyleSheetListener listener: listeners ) // listener.styleAdded( defaultRule, defaultRule ); // for( StyleSheetListener listener: listeners ) // listener.styleAdded( graphRules.defaultRule, graphRules.defaultRule // ); // for( StyleSheetListener listener: listeners ) // listener.styleAdded( nodeRules.defaultRule, nodeRules.defaultRule ); // for( StyleSheetListener listener: listeners ) // listener.styleAdded( edgeRules.defaultRule, edgeRules.defaultRule ); // for( StyleSheetListener listener: listeners ) // listener.styleAdded( spriteRules.defaultRule, spriteRules.defaultRule // ); }
// {{{ regexpBeanShellReplace() method private static String regexpBeanShellReplace( View view, JEditBuffer buffer, SearchMatcher.Match occur) throws Exception { replaceNS.setVariable("buffer", buffer, false); for (int i = 0; i < occur.substitutions.length; i++) { replaceNS.setVariable("_" + i, occur.substitutions[i]); } Object obj = BeanShell.runCachedBlock(replaceMethod, view, replaceNS); for (int i = 0; i < occur.substitutions.length; i++) { replaceNS.setVariable("_" + i, null, false); } // Not really necessary because it is already cleared in the end of // BeanShell.runCachedBlock() replaceNS.setVariable("buffer", null, false); if (obj == null) return ""; else return obj.toString(); } // }}}
public String getScriptStackTrace() { if (callstack == null) return "<Unknown>"; String trace = ""; CallStack stack = callstack.copy(); while (stack.depth() > 0) { NameSpace ns = stack.pop(); SimpleNode node = ns.getNode(); if (ns.isMethod) { trace = trace + "\nCalled from method: " + ns.getName(); if (node != null) trace += " : at Line: " + node.getLineNumber() + " : in file: " + node.getSourceFile() + " : " + node.getText(); } } return trace; }
// {{{ isSelected() method public boolean isSelected(Component comp) { if (isSelected == null) return false; NameSpace global = BeanShell.getNameSpace(); try { View view = GUIUtilities.getView(comp); // undocumented hack to allow browser actions to work. // XXX - clean up in 4.3 global.setVariable("_comp", comp); return Boolean.TRUE.equals( BeanShell.runCachedBlock( isSelected.get(), view, new NameSpace(BeanShell.getNameSpace(), "BeanShellAction.isSelected()"))); } catch (Throwable e) { Log.log(Log.ERROR, this, e); // dialogs f**k things up if a menu is visible, etc! // new BeanShellErrorDialog(view,e); // so that in the future we don't see streams of // exceptions isSelected = null; return false; } finally { try { global.setVariable("_comp", null); } catch (UtilEvalError err) { Log.log(Log.ERROR, this, err); } } } // }}}
public Name getName(NameSpace namespace) { return namespace.getNameResolver(text); }
/** * Parse the BSHBlock for for the class definition and generate the class using ClassGenerator. */ public static Class generateClassImpl( String name, Modifiers modifiers, Class[] interfaces, Class superClass, BSHBlock block, boolean isInterface, CallStack callstack, Interpreter interpreter) throws EvalError { // Scripting classes currently requires accessibility // This can be eliminated with a bit more work. try { Capabilities.setAccessibility(true); } catch (Capabilities.Unavailable e) { throw new EvalError( "Defining classes currently requires reflective Accessibility.", block, callstack); } NameSpace enclosingNameSpace = callstack.top(); String packageName = enclosingNameSpace.getPackage(); String className = enclosingNameSpace.isClass ? (enclosingNameSpace.getName() + "$" + name) : name; String fqClassName = packageName == null ? className : packageName + "." + className; BshClassManager bcm = interpreter.getClassManager(); // Race condition here... bcm.definingClass(fqClassName); // Create the class static namespace NameSpace classStaticNameSpace = new NameSpace(enclosingNameSpace, className); classStaticNameSpace.isClass = true; callstack.push(classStaticNameSpace); // Evaluate any inner class class definitions in the block // effectively recursively call this method for contained classes first block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSCLASSES); // Generate the type for our class Variable[] variables = getDeclaredVariables(block, callstack, interpreter, packageName); DelayedEvalBshMethod[] methods = getDeclaredMethods(block, callstack, interpreter, packageName); ClassGeneratorUtil classGenerator = new ClassGeneratorUtil( modifiers, className, packageName, superClass, interfaces, variables, methods, classStaticNameSpace, isInterface); byte[] code = classGenerator.generateClass(); // if debug, write out the class file to debugClasses directory if (DEBUG_DIR != null) try { FileOutputStream out = new FileOutputStream(DEBUG_DIR + '/' + className + ".class"); out.write(code); out.close(); } catch (IOException e) { throw new IllegalStateException( "cannot create file " + DEBUG_DIR + '/' + className + ".class", e); } // Define the new class in the classloader Class genClass = bcm.defineClass(fqClassName, code); // import the unq name into parent enclosingNameSpace.importClass(fqClassName.replace('$', '.')); try { classStaticNameSpace.setLocalVariable( ClassGeneratorUtil.BSHINIT, block, false /*strictJava*/); } catch (UtilEvalError e) { throw new InterpreterError("unable to init static: " + e); } // Give the static space its class static import // important to do this after all classes are defined classStaticNameSpace.setClassStatic(genClass); // evaluate the static portion of the block in the static space block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSSTATIC); callstack.pop(); if (!genClass.isInterface()) { // Set the static bsh This callback String bshStaticFieldName = ClassGeneratorUtil.BSHSTATIC + className; try { LHS lhs = Reflect.getLHSStaticField(genClass, bshStaticFieldName); lhs.assign(classStaticNameSpace.getThis(interpreter), false /*strict*/); } catch (Exception e) { throw new InterpreterError("Error in class gen setup: " + e); } } bcm.doneDefiningClass(fqClassName); return genClass; }