Index: lucene/build.xml
===================================================================
--- lucene/build.xml (revision 1358133)
+++ lucene/build.xml (working copy)
@@ -174,6 +174,11 @@
+
+
+
+
+
Index: lucene/tools/build.xml
===================================================================
--- lucene/tools/build.xml (revision 1358133)
+++ lucene/tools/build.xml (working copy)
@@ -24,7 +24,11 @@
-
+
+
+
+
+
-
+
+
+
Index: lucene/tools/custom-tasks.xml
===================================================================
--- lucene/tools/custom-tasks.xml (revision 1358133)
+++ lucene/tools/custom-tasks.xml (working copy)
@@ -55,4 +55,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: lucene/tools/ivy.xml
===================================================================
--- lucene/tools/ivy.xml (revision 1358133)
+++ lucene/tools/ivy.xml (working copy)
@@ -18,4 +18,8 @@
-->
+
+
+
+
Index: lucene/tools/lib
===================================================================
--- lucene/tools/lib (revision 0)
+++ lucene/tools/lib (working copy)
Property changes on: lucene/tools/lib
___________________________________________________________________
Added: svn:ignore
## -0,0 +1 ##
+*.jar
Index: lucene/tools/src/java/lucene-solr.antlib.xml
===================================================================
--- lucene/tools/src/java/lucene-solr.antlib.xml (revision 1358133)
+++ lucene/tools/src/java/lucene-solr.antlib.xml (working copy)
@@ -18,4 +18,7 @@
+
Index: lucene/tools/src/java/org/apache/lucene/validation/ForbiddenMethodCallCheckTask.java
===================================================================
--- lucene/tools/src/java/org/apache/lucene/validation/ForbiddenMethodCallCheckTask.java (revision 0)
+++ lucene/tools/src/java/org/apache/lucene/validation/ForbiddenMethodCallCheckTask.java (working copy)
@@ -0,0 +1,157 @@
+package org.apache.lucene.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.objectweb.asm.*;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Resources;
+
+import java.io.*;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * todo
+ */
+public class ForbiddenMethodCallCheckTask extends Task {
+
+ private Resources classFiles = new Resources();
+
+ /**
+ * Adds a set of JAR resources to check.
+ */
+ public void add(ResourceCollection rc) {
+ classFiles.add(rc);
+ }
+
+ static final Set forbiddenMethods = new HashSet();
+ static {
+ addConstructor(String.class, byte[].class);
+ addConstructor(String.class, byte[].class, int.class);
+ addConstructor(String.class, byte[].class, int.class, int.class);
+ addConstructor(String.class, byte[].class, int.class, int.class, int.class);
+ addMethod(String.class, "getBytes");
+ addMethod(String.class, "toLowerCase");
+ addMethod(String.class, "toUpperCase");
+ }
+
+ private static void addMethod(Class> clazz, String name, Class>... parameterTypes) {
+ try {
+ forbiddenMethods.add(
+ Type.getInternalName(clazz) + '#' + name +
+ Type.getMethodDescriptor(clazz.getDeclaredMethod(name, parameterTypes))
+ );
+ } catch (Exception e) {
+ throw new RuntimeException("Reflection problem: ", e);
+ }
+ }
+
+ private static void addConstructor(Class> clazz, Class>... parameterTypes) {
+ try {
+ forbiddenMethods.add(
+ Type.getInternalName(clazz) + "#" +
+ Type.getConstructorDescriptor(clazz.getConstructor(parameterTypes))
+ );
+ } catch (Exception e) {
+ throw new RuntimeException("Reflection problem: ", e);
+ }
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ classFiles.setProject(getProject());
+
+ long start = System.currentTimeMillis();
+
+ @SuppressWarnings("unchecked")
+ Iterator iter = (Iterator) classFiles.iterator();
+
+ int checked = 0;
+ int errors = 0;
+ while (iter.hasNext()) {
+ final Resource r = iter.next();
+ if (!r.isExists()) {
+ throw new BuildException("JAR resource does not exist: " + r.getName());
+ }
+ if (!(r instanceof FileResource)) {
+ throw new BuildException("Only filesystem resource are supported: " + r.getName()
+ + ", was: " + r.getClass().getName());
+ }
+
+ final File f = ((FileResource) r).getFile();
+ try {
+ errors += checkClass(f);
+ } catch (IOException ioe) {
+ throw new BuildException("IO problem while reading class file " + f, ioe);
+ }
+ checked++;
+ }
+
+ log(String.format(Locale.ENGLISH,
+ "Scanned %d class file(s) for forbidden method invocations (in %.2fs.), %d error(s).",
+ checked, (System.currentTimeMillis() - start) / 1000.0, errors),
+ errors > 0 ? Project.MSG_ERR : Project.MSG_INFO);
+
+ if (errors > 0) {
+ throw new BuildException("Check for forbidden method calls failed, see log.");
+ }
+ }
+
+ private final int checkClass(final File file) throws IOException {
+ InputStream stream = new BufferedInputStream(new FileInputStream(file));
+ try {
+ final int[] violations = new int[1];
+ new ClassReader(stream).accept(new EmptyVisitor() {
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ return new EmptyVisitor() {
+ private int lineNo;
+
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+ final String key = owner + '#' + name + desc;
+ if (forbiddenMethods.contains(key)) {
+ violations[0]++;
+ log(String.format(Locale.ENGLISH, "Forbidden method invocation: %s\n in %s, source line %d",
+ key, file.toString(), lineNo), Project.MSG_ERR);
+ }
+ }
+
+ @Override
+ public void visitLineNumber(int lineNo, Label start) {
+ this.lineNo = lineNo;
+ }
+ };
+ }
+ }, 0);
+ return violations[0];
+ } finally {
+ stream.close();
+ }
+ }
+
+}
Index: lucene/tools/src/java/org/apache/lucene/validation/ForbiddenMethodCallCheckTask.java
===================================================================
--- lucene/tools/src/java/org/apache/lucene/validation/ForbiddenMethodCallCheckTask.java (revision 0)
+++ lucene/tools/src/java/org/apache/lucene/validation/ForbiddenMethodCallCheckTask.java (working copy)
Property changes on: lucene/tools/src/java/org/apache/lucene/validation/ForbiddenMethodCallCheckTask.java
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Date Author Id Revision HeadURL
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property