Exemple #1
0
  /**
   * Given an abstract dispatch to an object of type c and a method m, gives a list of possible
   * receiver methods.
   */
  public List resolveAbstractDispatch(SootClass c, SootMethod m) {
    c.checkLevel(SootClass.HIERARCHY);
    m.getDeclaringClass().checkLevel(SootClass.HIERARCHY);
    checkState();

    Iterator<SootClass> classesIt = null;

    if (c.isInterface()) {
      classesIt = getImplementersOf(c).iterator();
      HashSet<SootClass> classes = new HashSet<SootClass>();
      while (classesIt.hasNext()) classes.addAll(getSubclassesOfIncluding(classesIt.next()));
      classesIt = classes.iterator();
    } else classesIt = getSubclassesOfIncluding(c).iterator();

    ArraySet s = new ArraySet();

    while (classesIt.hasNext()) {
      SootClass cl = classesIt.next();
      if (Modifier.isAbstract(cl.getModifiers())) continue;
      s.add(resolveConcreteDispatch(cl, m));
    }

    List l = new ArrayList();
    l.addAll(s);
    return Collections.unmodifiableList(l);
  }
  private <T> CachedRuleSource doExtract(final Class<T> source) {
    final ModelType<T> type = ModelType.of(source);
    DefaultMethodModelRuleExtractionContext context =
        new DefaultMethodModelRuleExtractionContext(type, this);

    // TODO - exceptions thrown here should point to some extensive documentation on the concept of
    // class rule sources

    StructSchema<T> schema = getSchema(source, context);
    if (schema == null) {
      throw new InvalidModelRuleDeclarationException(context.problems.format());
    }

    // sort for determinism
    Set<Method> methods = new TreeSet<Method>(Ordering.usingToString());
    methods.addAll(Arrays.asList(source.getDeclaredMethods()));

    ImmutableList.Builder<ModelProperty<?>> implicitInputs = ImmutableList.builder();
    ModelProperty<?> target = null;
    for (ModelProperty<?> property : schema.getProperties()) {
      if (property.isAnnotationPresent(RuleTarget.class)) {
        target = property;
      } else if (property.isAnnotationPresent(RuleInput.class)
          && !(property.getSchema() instanceof ScalarValueSchema)) {
        implicitInputs.add(property);
      }
      for (WeaklyTypeReferencingMethod<?, ?> method : property.getAccessors()) {
        methods.remove(method.getMethod());
      }
    }

    ImmutableList.Builder<ExtractedRuleDetails> rules = ImmutableList.builder();
    for (Method method : methods) {
      MethodRuleDefinition<?, ?> ruleDefinition =
          DefaultMethodRuleDefinition.create(source, method);
      ExtractedModelRule rule = getMethodHandler(ruleDefinition, method, context);
      if (rule != null) {
        rules.add(new ExtractedRuleDetails(ruleDefinition, rule));
      }
    }

    if (context.hasProblems()) {
      throw new InvalidModelRuleDeclarationException(context.problems.format());
    }

    StructBindings<T> bindings = structBindingsStore.getBindings(schema);

    if (schema.getProperties().isEmpty()) {
      return new StatelessRuleSource(
          rules.build(),
          Modifier.isAbstract(source.getModifiers())
              ? new AbstractRuleSourceFactory<T>(schema, bindings, proxyFactory)
              : new ConcreteRuleSourceFactory<T>(type));
    } else {
      return new ParameterizedRuleSource(
          rules.build(), target, implicitInputs.build(), schema, bindings, proxyFactory);
    }
  }
  private void validateRuleMethod(
      MethodRuleDefinition<?, ?> ruleDefinition,
      Method ruleMethod,
      ValidationProblemCollector problems) {
    if (Modifier.isPrivate(ruleMethod.getModifiers())) {
      problems.add(ruleMethod, "A rule method cannot be private");
    }
    if (Modifier.isAbstract(ruleMethod.getModifiers())) {
      problems.add(ruleMethod, "A rule method cannot be abstract");
    }

    if (ruleMethod.getTypeParameters().length > 0) {
      problems.add(ruleMethod, "Cannot have type variables (i.e. cannot be a generic method)");
    }

    // TODO validations on method: synthetic, bridge methods, varargs, abstract, native
    ModelType<?> returnType = ModelType.returnType(ruleMethod);
    if (returnType.isRawClassOfParameterizedType()) {
      problems.add(
          ruleMethod,
          "Raw type "
              + returnType
              + " used for return type (all type parameters must be specified of parameterized type)");
    }

    for (int i = 0; i < ruleDefinition.getReferences().size(); i++) {
      ModelReference<?> reference = ruleDefinition.getReferences().get(i);
      if (reference.getType().isRawClassOfParameterizedType()) {
        problems.add(
            ruleMethod,
            "Raw type "
                + reference.getType()
                + " used for parameter "
                + (i + 1)
                + " (all type parameters must be specified of parameterized type)");
      }
      if (reference.getPath() != null) {
        try {
          ModelPath.validatePath(reference.getPath().toString());
        } catch (Exception e) {
          problems.add(
              ruleDefinition,
              "The declared model element path '"
                  + reference.getPath()
                  + "' used for parameter "
                  + (i + 1)
                  + " is not a valid path",
              e);
        }
      }
    }
  }
  /**
   * Checks that a callback method is present and correctly defined.
   *
   * <p>Having checked it, you can call it using callback().
   *
   * @param sCallback Name of callback method
   * @throws OmDeveloperException If the method doesn't exist or is defined incorrectly
   */
  public void checkCallback(String sCallback) throws OmDeveloperException {
    try {
      Method m = getClass().getMethod(sCallback, new Class[0]);

      if (m.getReturnType() != void.class)
        throw new OmDeveloperException("Callback method " + sCallback + "() must return void");
      if (!Modifier.isPublic(m.getModifiers()))
        throw new OmDeveloperException("Callback method " + sCallback + "() must be public");
      if (Modifier.isStatic(m.getModifiers()))
        throw new OmDeveloperException("Callback method " + sCallback + "() may not be static");
      if (Modifier.isAbstract(m.getModifiers()))
        throw new OmDeveloperException("Callback method " + sCallback + "() may not be abstract");

      sCheckedCallbacks.add(sCallback);
    } catch (NoSuchMethodException e) {
      throw new OmDeveloperException("Callback method " + sCallback + "() does not exist");
    }
  }
Exemple #5
0
 /**
  * Checks if a class fulfills the JavaBeans contract.
  *
  * @param cls the class to check
  */
 public static void checkJavaBean(Class<?> cls) {
   try {
     Constructor<?> constructor = cls.getDeclaredConstructor();
     int classModifiers = cls.getModifiers();
     if (Modifier.isInterface(classModifiers))
       throw new RuntimeException(cls.getName() + " is an interface");
     if (Modifier.isAbstract(classModifiers))
       throw new RuntimeException(
           cls.getName() + " cannot be instantiated - it is an abstract class");
     int modifiers = constructor.getModifiers();
     if (!Modifier.isPublic(modifiers))
       throw new RuntimeException("No public default constructor in " + cls);
   } catch (NoSuchMethodException e) {
     throw new RuntimeException("No default constructor in class " + cls);
   } catch (SecurityException e) {
     logger.error(
         "I am not allowed to check the class by using reflection, "
             + "so I just can hope the class is alright and go on: ",
         e);
   }
 }
  public static void main(String[] args) throws Exception {
    System.out.println(
        "Checking that all known MBeans that are "
            + "NotificationBroadcasters have sane "
            + "MBeanInfo.getNotifications()");

    System.out.println("Checking platform MBeans...");
    checkPlatformMBeans();

    URL codeBase = ClassLoader.getSystemResource("javax/management/MBeanServer.class");
    if (codeBase == null) {
      throw new Exception("Could not determine codeBase for " + MBeanServer.class);
    }

    System.out.println();
    System.out.println("Looking for standard MBeans...");
    String[] classes = findStandardMBeans(codeBase);

    System.out.println("Testing standard MBeans...");
    for (int i = 0; i < classes.length; i++) {
      String name = classes[i];
      Class<?> c;
      try {
        c = Class.forName(name);
      } catch (Throwable e) {
        System.out.println(name + ": cannot load (not public?): " + e);
        continue;
      }
      if (!NotificationBroadcaster.class.isAssignableFrom(c)) {
        System.out.println(name + ": not a NotificationBroadcaster");
        continue;
      }
      if (Modifier.isAbstract(c.getModifiers())) {
        System.out.println(name + ": abstract class");
        continue;
      }

      NotificationBroadcaster mbean;
      Constructor<?> constr;
      try {
        constr = c.getConstructor();
      } catch (Exception e) {
        System.out.println(name + ": no public no-arg constructor: " + e);
        continue;
      }
      try {
        mbean = (NotificationBroadcaster) constr.newInstance();
      } catch (Exception e) {
        System.out.println(name + ": no-arg constructor failed: " + e);
        continue;
      }

      check(mbean);
    }

    System.out.println();
    System.out.println("Testing some explicit cases...");

    check(new RelationService(false));
    /*
      We can't do this:
        check(new RequiredModelMBean());
      because the Model MBean spec more or less forces us to use the
      names GENERIC and ATTRIBUTE_CHANGE for its standard notifs.
    */
    checkRMIConnectorServer();

    System.out.println();
    if (!suspicious.isEmpty()) System.out.println("SUSPICIOUS CLASSES: " + suspicious);

    if (failed.isEmpty()) System.out.println("TEST PASSED");
    else {
      System.out.println("TEST FAILED: " + failed);
      System.exit(1);
    }
  }
Exemple #7
0
  public void printTo(SootClass cl, PrintWriter out) {
    // add jimple line number tags
    setJimpleLnNum(1);

    // Print class name + modifiers
    {
      StringTokenizer st = new StringTokenizer(Modifier.toString(cl.getModifiers()));
      while (st.hasMoreTokens()) {
        String tok = (String) st.nextToken();
        if (cl.isInterface() && tok.equals("abstract")) continue;
        out.print(tok + " ");
      }

      String classPrefix = "";

      if (!cl.isInterface()) {
        classPrefix = classPrefix + " class";
        classPrefix = classPrefix.trim();
      }

      out.print(classPrefix + " " + Scene.v().quotedNameOf(cl.getName()) + "");
    }

    // Print extension
    {
      if (cl.hasSuperclass())
        out.print(" extends " + Scene.v().quotedNameOf(cl.getSuperclass().getName()) + "");
    }

    // Print interfaces
    {
      Iterator interfaceIt = cl.getInterfaces().iterator();

      if (interfaceIt.hasNext()) {
        out.print(" implements ");

        out.print("" + Scene.v().quotedNameOf(((SootClass) interfaceIt.next()).getName()) + "");

        while (interfaceIt.hasNext()) {
          out.print(",");
          out.print(" " + Scene.v().quotedNameOf(((SootClass) interfaceIt.next()).getName()) + "");
        }
      }
    }

    out.println();
    incJimpleLnNum();
    /*        if (!addJimpleLn()) {
        Iterator clTagsIt = cl.getTags().iterator();
        while (clTagsIt.hasNext()) {
            final Tag t = (Tag)clTagsIt.next();
            out.println(t);
        }
    }*/
    out.println("{");
    incJimpleLnNum();
    if (Options.v().print_tags_in_output()) {
      Iterator cTagIterator = cl.getTags().iterator();
      while (cTagIterator.hasNext()) {
        Tag t = (Tag) cTagIterator.next();
        out.print("/*");
        out.print(t.toString());
        out.println("*/");
      }
    }

    // Print fields
    {
      Iterator fieldIt = cl.getFields().iterator();

      if (fieldIt.hasNext()) {
        while (fieldIt.hasNext()) {
          SootField f = (SootField) fieldIt.next();

          if (f.isPhantom()) continue;

          if (Options.v().print_tags_in_output()) {
            Iterator fTagIterator = f.getTags().iterator();
            while (fTagIterator.hasNext()) {
              Tag t = (Tag) fTagIterator.next();
              out.print("/*");
              out.print(t.toString());
              out.println("*/");
            }
          }
          out.println("    " + f.getDeclaration() + ";");
          if (addJimpleLn()) {
            setJimpleLnNum(addJimpleLnTags(getJimpleLnNum(), f));
          }

          // incJimpleLnNum();
        }
      }
    }

    // Print methods
    {
      Iterator methodIt = cl.methodIterator();

      if (methodIt.hasNext()) {
        if (cl.getMethodCount() != 0) {
          out.println();
          incJimpleLnNum();
        }

        while (methodIt.hasNext()) {
          SootMethod method = (SootMethod) methodIt.next();

          if (method.isPhantom()) continue;

          if (!Modifier.isAbstract(method.getModifiers())
              && !Modifier.isNative(method.getModifiers())) {
            if (!method.hasActiveBody())
              throw new RuntimeException("method " + method.getName() + " has no active body!");
            else if (Options.v().print_tags_in_output()) {
              Iterator mTagIterator = method.getTags().iterator();
              while (mTagIterator.hasNext()) {
                Tag t = (Tag) mTagIterator.next();
                out.print("/*");
                out.print(t.toString());
                out.println("*/");
              }
            }
            printTo(method.getActiveBody(), out);

            if (methodIt.hasNext()) {
              out.println();
              incJimpleLnNum();
            }
          } else {

            if (Options.v().print_tags_in_output()) {
              Iterator mTagIterator = method.getTags().iterator();
              while (mTagIterator.hasNext()) {
                Tag t = (Tag) mTagIterator.next();
                out.print("/*");
                out.print(t.toString());
                out.println("*/");
              }
            }

            out.print("    ");
            out.print(method.getDeclaration());
            out.println(";");
            incJimpleLnNum();
            if (methodIt.hasNext()) {
              out.println();
              incJimpleLnNum();
            }
          }
        }
      }
    }
    out.println("}");
    incJimpleLnNum();
  }
 protected void loadHttpServlet(final AnyValue conf, final ClassFilter<? extends Servlet> filter)
     throws Exception {
   final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
   final String prefix = conf == null ? "" : conf.getValue("path", "");
   final String threadName = "[" + Thread.currentThread().getName() + "] ";
   List<FilterEntry<? extends Servlet>> list = new ArrayList(filter.getFilterEntrys());
   list.sort(
       (FilterEntry<? extends Servlet> o1,
           FilterEntry<? extends Servlet>
               o2) -> { // 必须保证WebSocketServlet优先加载, 因为要确保其他的HttpServlet可以注入本地模式的WebSocketNode
         boolean ws1 = WebSocketServlet.class.isAssignableFrom(o1.getType());
         boolean ws2 = WebSocketServlet.class.isAssignableFrom(o2.getType());
         if (ws1 == ws2) return o1.getType().getName().compareTo(o2.getType().getName());
         return ws1 ? -1 : 1;
       });
   final List<AbstractMap.SimpleEntry<String, String[]>> ss =
       sb == null ? null : new ArrayList<>();
   for (FilterEntry<? extends Servlet> en : list) {
     Class<HttpServlet> clazz = (Class<HttpServlet>) en.getType();
     if (Modifier.isAbstract(clazz.getModifiers())) continue;
     WebServlet ws = clazz.getAnnotation(WebServlet.class);
     if (ws == null || ws.value().length == 0) continue;
     final HttpServlet servlet = clazz.newInstance();
     resourceFactory.inject(servlet, this);
     final String[] mappings = ws.value();
     String pref = ws.repair() ? prefix : "";
     DefaultAnyValue servletConf = (DefaultAnyValue) en.getProperty();
     WebInitParam[] webparams = ws.initParams();
     if (webparams.length > 0) {
       if (servletConf == null) servletConf = new DefaultAnyValue();
       for (WebInitParam webparam : webparams) {
         servletConf.addValue(webparam.name(), webparam.value());
       }
     }
     this.httpServer.addHttpServlet(servlet, pref, servletConf, mappings);
     if (ss != null) {
       for (int i = 0; i < mappings.length; i++) {
         mappings[i] = pref + mappings[i];
       }
       ss.add(new AbstractMap.SimpleEntry<>(clazz.getName(), mappings));
     }
   }
   if (ss != null) {
     Collections.sort(
         ss,
         (AbstractMap.SimpleEntry<String, String[]> o1,
             AbstractMap.SimpleEntry<String, String[]> o2) -> o1.getKey().compareTo(o2.getKey()));
     int max = 0;
     for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
       if (as.getKey().length() > max) max = as.getKey().length();
     }
     for (AbstractMap.SimpleEntry<String, String[]> as : ss) {
       sb.append(threadName).append(" Loaded ").append(as.getKey());
       for (int i = 0; i < max - as.getKey().length(); i++) {
         sb.append(' ');
       }
       sb.append("  mapping to  ").append(Arrays.toString(as.getValue())).append(LINE_SEPARATOR);
     }
   }
   if (sb != null && sb.length() > 0) logger.log(Level.INFO, sb.toString());
 }
  public static byte[] createAdapterCode(
      ObjToIntMap functionNames,
      String adapterName,
      Class<?> superClass,
      Class<?>[] interfaces,
      String scriptClassName) {
    ClassFileWriter cfw = new ClassFileWriter(adapterName, superClass.getName(), "<adapter>");
    cfw.addField(
        "factory",
        "Laurora/javascript/ContextFactory;",
        (short) (ClassFileWriter.ACC_PUBLIC | ClassFileWriter.ACC_FINAL));
    cfw.addField(
        "delegee",
        "Laurora/javascript/Scriptable;",
        (short) (ClassFileWriter.ACC_PUBLIC | ClassFileWriter.ACC_FINAL));
    cfw.addField(
        "self",
        "Laurora/javascript/Scriptable;",
        (short) (ClassFileWriter.ACC_PUBLIC | ClassFileWriter.ACC_FINAL));
    int interfacesCount = interfaces == null ? 0 : interfaces.length;
    for (int i = 0; i < interfacesCount; i++) {
      if (interfaces[i] != null) cfw.addInterface(interfaces[i].getName());
    }

    String superName = superClass.getName().replace('.', '/');
    Constructor<?>[] ctors = superClass.getConstructors();
    for (Constructor<?> ctor : ctors) {
      generateCtor(cfw, adapterName, superName, ctor);
    }
    generateSerialCtor(cfw, adapterName, superName);
    if (scriptClassName != null) {
      generateEmptyCtor(cfw, adapterName, superName, scriptClassName);
    }

    ObjToIntMap generatedOverrides = new ObjToIntMap();
    ObjToIntMap generatedMethods = new ObjToIntMap();

    // generate methods to satisfy all specified interfaces.
    for (int i = 0; i < interfacesCount; i++) {
      Method[] methods = interfaces[i].getMethods();
      for (int j = 0; j < methods.length; j++) {
        Method method = methods[j];
        int mods = method.getModifiers();
        if (Modifier.isStatic(mods) || Modifier.isFinal(mods)) {
          continue;
        }
        String methodName = method.getName();
        Class<?>[] argTypes = method.getParameterTypes();
        if (!functionNames.has(methodName)) {
          try {
            superClass.getMethod(methodName, argTypes);
            // The class we're extending implements this method and
            // the JavaScript object doesn't have an override. See
            // bug 61226.
            continue;
          } catch (NoSuchMethodException e) {
            // Not implemented by superclass; fall through
          }
        }
        // make sure to generate only one instance of a particular
        // method/signature.
        String methodSignature = getMethodSignature(method, argTypes);
        String methodKey = methodName + methodSignature;
        if (!generatedOverrides.has(methodKey)) {
          generateMethod(cfw, adapterName, methodName, argTypes, method.getReturnType(), true);
          generatedOverrides.put(methodKey, 0);
          generatedMethods.put(methodName, 0);
        }
      }
    }

    // Now, go through the superclass's methods, checking for abstract
    // methods or additional methods to override.

    // generate any additional overrides that the object might contain.
    Method[] methods = getOverridableMethods(superClass);
    for (int j = 0; j < methods.length; j++) {
      Method method = methods[j];
      int mods = method.getModifiers();
      // if a method is marked abstract, must implement it or the
      // resulting class won't be instantiable. otherwise, if the object
      // has a property of the same name, then an override is intended.
      boolean isAbstractMethod = Modifier.isAbstract(mods);
      String methodName = method.getName();
      if (isAbstractMethod || functionNames.has(methodName)) {
        // make sure to generate only one instance of a particular
        // method/signature.
        Class<?>[] argTypes = method.getParameterTypes();
        String methodSignature = getMethodSignature(method, argTypes);
        String methodKey = methodName + methodSignature;
        if (!generatedOverrides.has(methodKey)) {
          generateMethod(cfw, adapterName, methodName, argTypes, method.getReturnType(), true);
          generatedOverrides.put(methodKey, 0);
          generatedMethods.put(methodName, 0);

          // if a method was overridden, generate a "super$method"
          // which lets the delegate call the superclass' version.
          if (!isAbstractMethod) {
            generateSuper(
                cfw,
                adapterName,
                superName,
                methodName,
                methodSignature,
                argTypes,
                method.getReturnType());
          }
        }
      }
    }

    // Generate Java methods for remaining properties that are not
    // overrides.
    ObjToIntMap.Iterator iter = new ObjToIntMap.Iterator(functionNames);
    for (iter.start(); !iter.done(); iter.next()) {
      String functionName = (String) iter.getKey();
      if (generatedMethods.has(functionName)) continue;
      int length = iter.getValue();
      Class<?>[] parms = new Class[length];
      for (int k = 0; k < length; k++) parms[k] = ScriptRuntime.ObjectClass;
      generateMethod(cfw, adapterName, functionName, parms, ScriptRuntime.ObjectClass, false);
    }
    return cfw.toByteArray();
  }