Backed out changeset 4a2cfb7f789e
authorJesse Glick <jglick@netbeans.org>
Fri, 22 Jan 2010 10:09:12 -0500
changeset 9687479a9c25061
parent 967 793a9628c24b
child 969 fdbfdc759045
Backed out changeset 4a2cfb7f789e
Being done differently in #179289.
openide.util.lookup/src/org/netbeans/modules/openide/util/AbstractServiceProviderProcessor.java
openide.util.lookup/src/org/netbeans/modules/openide/util/ActiveQueue.java
openide.util/nbproject/project.xml
openide.util/src/org/netbeans/modules/openide/util/AbstractServiceProviderProcessor.java
openide.util/src/org/netbeans/modules/openide/util/ActiveQueue.java
     1.1 --- a/openide.util.lookup/src/org/netbeans/modules/openide/util/AbstractServiceProviderProcessor.java	Fri Jan 22 14:50:19 2010 +0100
     1.2 +++ b/openide.util.lookup/src/org/netbeans/modules/openide/util/AbstractServiceProviderProcessor.java	Fri Jan 22 10:09:12 2010 -0500
     1.3 @@ -72,8 +72,6 @@
     1.4  /**
     1.5   * Infrastructure for generating {@code META-INF/services/*} and
     1.6   * {@code META-INF/namedservices/*} registrations from annotations.
     1.7 - *
     1.8 - * NOTE: This class is duplicated in openide.util and openide.util.lookup to prevent implementation dependency.
     1.9   */
    1.10  public abstract class AbstractServiceProviderProcessor extends AbstractProcessor {
    1.11  
     2.1 --- a/openide.util.lookup/src/org/netbeans/modules/openide/util/ActiveQueue.java	Fri Jan 22 14:50:19 2010 +0100
     2.2 +++ b/openide.util.lookup/src/org/netbeans/modules/openide/util/ActiveQueue.java	Fri Jan 22 10:09:12 2010 -0500
     2.3 @@ -7,8 +7,6 @@
     2.4  
     2.5  /**
     2.6   * Implementation of the active reference queue.
     2.7 - *
     2.8 - * NOTE: This class is duplicated in openide.util and openide.util.lookup to prevent implementation dependency.
     2.9   */
    2.10  public final class ActiveQueue extends ReferenceQueue<Object> implements Runnable {
    2.11  
     3.1 --- a/openide.util/nbproject/project.xml	Fri Jan 22 14:50:19 2010 +0100
     3.2 +++ b/openide.util/nbproject/project.xml	Fri Jan 22 10:09:12 2010 -0500
     3.3 @@ -51,7 +51,7 @@
     3.4                      <build-prerequisite/>
     3.5                      <compile-dependency/>
     3.6                      <run-dependency>
     3.7 -                        <specification-version>8.0</specification-version>
     3.8 +                        <implementation-version/>
     3.9                      </run-dependency>
    3.10                  </dependency>
    3.11              </module-dependencies>
     4.1 --- a/openide.util/src/org/netbeans/modules/openide/util/AbstractServiceProviderProcessor.java	Fri Jan 22 14:50:19 2010 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,298 +0,0 @@
     4.4 -/*
     4.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 - *
     4.7 - * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
     4.8 - *
     4.9 - * The contents of this file are subject to the terms of either the GNU
    4.10 - * General Public License Version 2 only ("GPL") or the Common
    4.11 - * Development and Distribution License("CDDL") (collectively, the
    4.12 - * "License"). You may not use this file except in compliance with the
    4.13 - * License. You can obtain a copy of the License at
    4.14 - * http://www.netbeans.org/cddl-gplv2.html
    4.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    4.16 - * specific language governing permissions and limitations under the
    4.17 - * License.  When distributing the software, include this License Header
    4.18 - * Notice in each file and include the License file at
    4.19 - * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    4.20 - * particular file as subject to the "Classpath" exception as provided
    4.21 - * by Sun in the GPL Version 2 section of the License file that
    4.22 - * accompanied this code. If applicable, add the following below the
    4.23 - * License Header, with the fields enclosed by brackets [] replaced by
    4.24 - * your own identifying information:
    4.25 - * "Portions Copyrighted [year] [name of copyright owner]"
    4.26 - *
    4.27 - * If you wish your version of this file to be governed by only the CDDL
    4.28 - * or only the GPL Version 2, indicate your decision by adding
    4.29 - * "[Contributor] elects to include this software in this distribution
    4.30 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
    4.31 - * single choice of license, a recipient has the option to distribute
    4.32 - * your version of this file under either the CDDL, the GPL Version 2 or
    4.33 - * to extend the choice of license to its licensees as provided above.
    4.34 - * However, if you add GPL Version 2 code and therefore, elected the GPL
    4.35 - * Version 2 license, then the option applies only if the new code is
    4.36 - * made subject to such option by the copyright holder.
    4.37 - *
    4.38 - * Contributor(s):
    4.39 - *
    4.40 - * Portions Copyrighted 2009 Sun Microsystems, Inc.
    4.41 - */
    4.42 -
    4.43 -package org.netbeans.modules.openide.util;
    4.44 -
    4.45 -import java.io.BufferedReader;
    4.46 -import java.io.FileNotFoundException;
    4.47 -import java.io.IOException;
    4.48 -import java.io.InputStream;
    4.49 -import java.io.InputStreamReader;
    4.50 -import java.io.OutputStream;
    4.51 -import java.io.OutputStreamWriter;
    4.52 -import java.io.PrintWriter;
    4.53 -import java.lang.annotation.Annotation;
    4.54 -import java.util.ArrayList;
    4.55 -import java.util.HashMap;
    4.56 -import java.util.List;
    4.57 -import java.util.Map;
    4.58 -import java.util.Set;
    4.59 -import java.util.WeakHashMap;
    4.60 -import javax.annotation.processing.AbstractProcessor;
    4.61 -import javax.annotation.processing.ProcessingEnvironment;
    4.62 -import javax.annotation.processing.RoundEnvironment;
    4.63 -import javax.lang.model.element.AnnotationMirror;
    4.64 -import javax.lang.model.element.AnnotationValue;
    4.65 -import javax.lang.model.element.Element;
    4.66 -import javax.lang.model.element.ExecutableElement;
    4.67 -import javax.lang.model.element.Modifier;
    4.68 -import javax.lang.model.element.TypeElement;
    4.69 -import javax.lang.model.type.TypeMirror;
    4.70 -import javax.lang.model.util.ElementFilter;
    4.71 -import javax.tools.Diagnostic.Kind;
    4.72 -import javax.tools.FileObject;
    4.73 -import javax.tools.StandardLocation;
    4.74 -
    4.75 -/**
    4.76 - * Infrastructure for generating {@code META-INF/services/*} and
    4.77 - * {@code META-INF/namedservices/*} registrations from annotations.
    4.78 - *
    4.79 - * NOTE: This class is duplicated in openide.util and openide.util.lookup to prevent implementation dependency.
    4.80 - */
    4.81 -public abstract class AbstractServiceProviderProcessor extends AbstractProcessor {
    4.82 -
    4.83 -    private final Map<ProcessingEnvironment,Map<String,List<String>>> outputFilesByProcessor = new WeakHashMap<ProcessingEnvironment,Map<String,List<String>>>();
    4.84 -    private final Map<ProcessingEnvironment,Map<String,List<Element>>> originatingElementsByProcessor = new WeakHashMap<ProcessingEnvironment,Map<String,List<Element>>>();
    4.85 -    private final Map<TypeElement,Boolean> verifiedClasses = new WeakHashMap<TypeElement,Boolean>();
    4.86 -
    4.87 -    /** For access by subclasses. */
    4.88 -    protected AbstractServiceProviderProcessor() {}
    4.89 -
    4.90 -    public @Override final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    4.91 -        if (roundEnv.errorRaised()) {
    4.92 -            return false;
    4.93 -        }
    4.94 -        if (roundEnv.processingOver()) {
    4.95 -            writeServices();
    4.96 -            outputFilesByProcessor.clear();
    4.97 -            originatingElementsByProcessor.clear();
    4.98 -            return true;
    4.99 -        } else {
   4.100 -            return handleProcess(annotations, roundEnv);
   4.101 -        }
   4.102 -    }
   4.103 -
   4.104 -    /**
   4.105 -     * The regular body of {@link #process}.
   4.106 -     * Called during regular rounds if there are no outstanding errors.
   4.107 -     * In the last round, one of the processors will write out generated registrations.
   4.108 -     * @param annotations as in {@link #process}
   4.109 -     * @param roundEnv as in {@link #process}
   4.110 -     * @return as in {@link #process}
   4.111 -     */
   4.112 -    protected abstract boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv);
   4.113 -
   4.114 -    /**
   4.115 -     * Register a service.
   4.116 -     * If the class does not have an appropriate signature, an error will be printed and the registration skipped.
   4.117 -     * @param clazz the service implementation type
   4.118 -     * @param annotation the (top-level) annotation registering the service, for diagnostic purposes
   4.119 -     * @param type the type to which the implementation must be assignable
   4.120 -     * @param path a path under which to register, or "" if inapplicable
   4.121 -     * @param position a position at which to register, or {@link Integer#MAX_VALUE} to skip
   4.122 -     * @param supersedes possibly empty list of implementation to supersede
   4.123 -     */
   4.124 -    protected final void register(TypeElement clazz, Class<? extends Annotation> annotation,
   4.125 -            TypeMirror type, String path, int position, String[] supersedes) {
   4.126 -        Boolean verify = verifiedClasses.get(clazz);
   4.127 -        if (verify == null) {
   4.128 -            verify = verifyServiceProviderSignature(clazz, annotation);
   4.129 -            verifiedClasses.put(clazz, verify);
   4.130 -        }
   4.131 -        if (!verify) {
   4.132 -            return;
   4.133 -        }
   4.134 -        String impl = processingEnv.getElementUtils().getBinaryName(clazz).toString();
   4.135 -        String xface = processingEnv.getElementUtils().getBinaryName((TypeElement) processingEnv.getTypeUtils().asElement(type)).toString();
   4.136 -        if (!processingEnv.getTypeUtils().isAssignable(clazz.asType(), type)) {
   4.137 -            AnnotationMirror ann = findAnnotationMirror(clazz, annotation);
   4.138 -            processingEnv.getMessager().printMessage(Kind.ERROR, impl + " is not assignable to " + xface,
   4.139 -                    clazz, ann, findAnnotationValue(ann, "service"));
   4.140 -            return;
   4.141 -        }
   4.142 -        processingEnv.getMessager().printMessage(Kind.NOTE,
   4.143 -                impl + " to be registered as a " + xface + (path.length() > 0 ? " under " + path : ""));
   4.144 -        String rsrc = (path.length() > 0 ? "META-INF/namedservices/" + path + "/" : "META-INF/services/") + xface;
   4.145 -        {
   4.146 -            Map<String,List<Element>> originatingElements = originatingElementsByProcessor.get(processingEnv);
   4.147 -            if (originatingElements == null) {
   4.148 -                originatingElements = new HashMap<String,List<Element>>();
   4.149 -                originatingElementsByProcessor.put(processingEnv, originatingElements);
   4.150 -            }
   4.151 -            List<Element> origEls = originatingElements.get(rsrc);
   4.152 -            if (origEls == null) {
   4.153 -                origEls = new ArrayList<Element>();
   4.154 -                originatingElements.put(rsrc, origEls);
   4.155 -            }
   4.156 -            origEls.add(clazz);
   4.157 -        }
   4.158 -        Map<String,List<String>> outputFiles = outputFilesByProcessor.get(processingEnv);
   4.159 -        if (outputFiles == null) {
   4.160 -            outputFiles = new HashMap<String,List<String>>();
   4.161 -            outputFilesByProcessor.put(processingEnv, outputFiles);
   4.162 -        }
   4.163 -        List<String> lines = outputFiles.get(rsrc);
   4.164 -        if (lines == null) {
   4.165 -            lines = new ArrayList<String>();
   4.166 -            try {
   4.167 -                try {
   4.168 -                    FileObject in = processingEnv.getFiler().getResource(StandardLocation.SOURCE_PATH, "", rsrc);
   4.169 -                    in.openInputStream().close();
   4.170 -                    processingEnv.getMessager().printMessage(Kind.ERROR,
   4.171 -                            "Cannot generate " + rsrc + " because it already exists in sources: " + in.toUri());
   4.172 -                    return;
   4.173 -                } catch (NullPointerException ex) {
   4.174 -                    // trying to prevent java.lang.NullPointerException
   4.175 -                    // at com.sun.tools.javac.util.DefaultFileManager.getFileForOutput(DefaultFileManager.java:1078)
   4.176 -                    // at com.sun.tools.javac.util.DefaultFileManager.getFileForOutput(DefaultFileManager.java:1054)
   4.177 -                    // at com.sun.tools.javac.processing.JavacFiler.getResource(JavacFiler.java:434)
   4.178 -                    // at org.netbeans.modules.openide.util.AbstractServiceProviderProcessor.register(AbstractServiceProviderProcessor.java:163)
   4.179 -                    // at org.netbeans.modules.openide.util.ServiceProviderProcessor.register(ServiceProviderProcessor.java:99)
   4.180 -                } catch (FileNotFoundException x) {
   4.181 -                    // Good.
   4.182 -                }
   4.183 -                try {
   4.184 -                    FileObject in = processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", rsrc);
   4.185 -                    InputStream is = in.openInputStream();
   4.186 -                    try {
   4.187 -                        BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF-8"));
   4.188 -                        String line;
   4.189 -                        while ((line = r.readLine()) != null) {
   4.190 -                            lines.add(line);
   4.191 -                        }
   4.192 -                    } finally {
   4.193 -                        is.close();
   4.194 -                    }
   4.195 -                } catch (FileNotFoundException x) {
   4.196 -                    // OK, created for the first time
   4.197 -                }
   4.198 -            } catch (IOException x) {
   4.199 -                processingEnv.getMessager().printMessage(Kind.ERROR, x.toString());
   4.200 -                return;
   4.201 -            }
   4.202 -            outputFiles.put(rsrc, lines);
   4.203 -        }
   4.204 -        int idx = lines.indexOf(impl);
   4.205 -        if (idx != -1) {
   4.206 -            lines.remove(idx);
   4.207 -            while (lines.size() > idx && lines.get(idx).matches("#position=.+|#-.+")) {
   4.208 -                lines.remove(idx);
   4.209 -            }
   4.210 -        }
   4.211 -        lines.add(impl);
   4.212 -        if (position != Integer.MAX_VALUE) {
   4.213 -            lines.add("#position=" + position);
   4.214 -        }
   4.215 -        for (String exclude : supersedes) {
   4.216 -            lines.add("#-" + exclude);
   4.217 -        }
   4.218 -    }
   4.219 -
   4.220 -    /**
   4.221 -     * @param element a source element
   4.222 -     * @param annotation a type of annotation
   4.223 -     * @return the instance of that annotation on the element, or null if not found
   4.224 -     */
   4.225 -    private AnnotationMirror findAnnotationMirror(Element element, Class<? extends Annotation> annotation) {
   4.226 -        for (AnnotationMirror ann : element.getAnnotationMirrors()) {
   4.227 -            if (processingEnv.getElementUtils().getBinaryName((TypeElement) ann.getAnnotationType().asElement()).
   4.228 -                    contentEquals(annotation.getName())) {
   4.229 -                return ann;
   4.230 -            }
   4.231 -        }
   4.232 -        return null;
   4.233 -    }
   4.234 -
   4.235 -    /**
   4.236 -     * @param annotation an annotation instance (null permitted)
   4.237 -     * @param name the name of an attribute of that annotation
   4.238 -     * @return the corresponding value if found
   4.239 -     */
   4.240 -    private AnnotationValue findAnnotationValue(AnnotationMirror annotation, String name) {
   4.241 -        if (annotation != null) {
   4.242 -            for (Map.Entry<? extends ExecutableElement,? extends AnnotationValue> entry : annotation.getElementValues().entrySet()) {
   4.243 -                if (entry.getKey().getSimpleName().contentEquals(name)) {
   4.244 -                    return entry.getValue();
   4.245 -                }
   4.246 -            }
   4.247 -        }
   4.248 -        return null;
   4.249 -    }
   4.250 -
   4.251 -    private final boolean verifyServiceProviderSignature(TypeElement clazz, Class<? extends Annotation> annotation) {
   4.252 -        AnnotationMirror ann = findAnnotationMirror(clazz, annotation);
   4.253 -        if (!clazz.getModifiers().contains(Modifier.PUBLIC)) {
   4.254 -            processingEnv.getMessager().printMessage(Kind.ERROR, clazz + " must be public", clazz, ann);
   4.255 -            return false;
   4.256 -        }
   4.257 -        if (clazz.getModifiers().contains(Modifier.ABSTRACT)) {
   4.258 -            processingEnv.getMessager().printMessage(Kind.ERROR, clazz + " must not be abstract", clazz, ann);
   4.259 -            return false;
   4.260 -        }
   4.261 -        {
   4.262 -            boolean hasDefaultCtor = false;
   4.263 -            for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) {
   4.264 -                if (constructor.getModifiers().contains(Modifier.PUBLIC) && constructor.getParameters().isEmpty()) {
   4.265 -                    hasDefaultCtor = true;
   4.266 -                    break;
   4.267 -                }
   4.268 -            }
   4.269 -            if (!hasDefaultCtor) {
   4.270 -                processingEnv.getMessager().printMessage(Kind.ERROR, clazz + " must have a public no-argument constructor", clazz, ann);
   4.271 -                return false;
   4.272 -            }
   4.273 -        }
   4.274 -        return true;
   4.275 -    }
   4.276 -
   4.277 -    private void writeServices() {
   4.278 -        for (Map.Entry<ProcessingEnvironment,Map<String,List<String>>> outputFiles : outputFilesByProcessor.entrySet()) {
   4.279 -            for (Map.Entry<String, List<String>> entry : outputFiles.getValue().entrySet()) {
   4.280 -                try {
   4.281 -                    FileObject out = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", entry.getKey(),
   4.282 -                            originatingElementsByProcessor.get(outputFiles.getKey()).get(entry.getKey()).toArray(new Element[0]));
   4.283 -                    OutputStream os = out.openOutputStream();
   4.284 -                    try {
   4.285 -                        PrintWriter w = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
   4.286 -                        for (String line : entry.getValue()) {
   4.287 -                            w.println(line);
   4.288 -                        }
   4.289 -                        w.flush();
   4.290 -                        w.close();
   4.291 -                    } finally {
   4.292 -                        os.close();
   4.293 -                    }
   4.294 -                } catch (IOException x) {
   4.295 -                    processingEnv.getMessager().printMessage(Kind.ERROR, "Failed to write to " + entry.getKey() + ": " + x.toString());
   4.296 -                }
   4.297 -            }
   4.298 -        }
   4.299 -    }
   4.300 -
   4.301 -}
     5.1 --- a/openide.util/src/org/netbeans/modules/openide/util/ActiveQueue.java	Fri Jan 22 14:50:19 2010 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,110 +0,0 @@
     5.4 -package org.netbeans.modules.openide.util;
     5.5 -
     5.6 -import java.lang.ref.Reference;
     5.7 -import java.lang.ref.ReferenceQueue;
     5.8 -import java.util.logging.Level;
     5.9 -import java.util.logging.Logger;
    5.10 -
    5.11 -/**
    5.12 - * Implementation of the active reference queue.
    5.13 - *
    5.14 - * NOTE: This class is duplicated in openide.util and openide.util.lookup to prevent implementation dependency.
    5.15 - */
    5.16 -public final class ActiveQueue extends ReferenceQueue<Object> implements Runnable {
    5.17 -
    5.18 -    private static final Logger LOGGER = Logger.getLogger(ActiveQueue.class.getName().replace('$', '.'));
    5.19 -    private static ActiveQueue activeReferenceQueue;
    5.20 -    
    5.21 -    /** number of known outstanding references */
    5.22 -    private int count;
    5.23 -    private boolean deprecated;
    5.24 -
    5.25 -    ActiveQueue(boolean deprecated) {
    5.26 -        super();
    5.27 -        this.deprecated = deprecated;
    5.28 -    }
    5.29 -
    5.30 -    public static synchronized ReferenceQueue<Object> queue() {
    5.31 -        if (activeReferenceQueue == null) {
    5.32 -            activeReferenceQueue = new ActiveQueue(false);
    5.33 -        }
    5.34 -
    5.35 -        activeReferenceQueue.ping();
    5.36 -
    5.37 -        return activeReferenceQueue;
    5.38 -    }
    5.39 -
    5.40 -    @Override
    5.41 -    public Reference<Object> poll() {
    5.42 -        throw new UnsupportedOperationException();
    5.43 -    }
    5.44 -
    5.45 -    @Override
    5.46 -    public Reference<Object> remove(long timeout) throws IllegalArgumentException, InterruptedException {
    5.47 -        throw new InterruptedException();
    5.48 -    }
    5.49 -
    5.50 -    @Override
    5.51 -    public Reference<Object> remove() throws InterruptedException {
    5.52 -        throw new InterruptedException();
    5.53 -    }
    5.54 -
    5.55 -    public void run() {
    5.56 -        while (true) {
    5.57 -            try {
    5.58 -                Reference<?> ref = super.remove(0);
    5.59 -                LOGGER.finer("dequeued reference");
    5.60 -                if (!(ref instanceof Runnable)) {
    5.61 -                    LOGGER.warning("A reference not implementing runnable has been added to the Utilities.activeReferenceQueue(): " + ref.getClass());
    5.62 -                    continue;
    5.63 -                }
    5.64 -                if (deprecated) {
    5.65 -                    LOGGER.warning("Utilities.ACTIVE_REFERENCE_QUEUE has been deprecated for " + ref.getClass() + " use Utilities.activeReferenceQueue");
    5.66 -                }
    5.67 -                // do the cleanup
    5.68 -                try {
    5.69 -                    ((Runnable) ref).run();
    5.70 -                } catch (ThreadDeath td) {
    5.71 -                    throw td;
    5.72 -                } catch (Throwable t) {
    5.73 -                    // Should not happen.
    5.74 -                    // If it happens, it is a bug in client code, notify!
    5.75 -                    LOGGER.log(Level.WARNING, null, t);
    5.76 -                } finally {
    5.77 -                    // to allow GC
    5.78 -                    ref = null;
    5.79 -                }
    5.80 -            } catch (InterruptedException ex) {
    5.81 -                // Can happen during VM shutdown, it seems. Ignore.
    5.82 -                continue;
    5.83 -            }
    5.84 -            synchronized (this) {
    5.85 -                assert count > 0;
    5.86 -                count--;
    5.87 -                if (count == 0) {
    5.88 -                    // We have processed all we have to process (for now at least).
    5.89 -                    // Could be restarted later if ping() called again.
    5.90 -                    // This could also happen in case someone called queue() once and tried
    5.91 -                    // to use it for several references; in that case run() might never be called on
    5.92 -                    // the later ones to be collected. Can't really protect against that situation.
    5.93 -                    // See issue #86625 for details.
    5.94 -                    LOGGER.fine("stopping thread");
    5.95 -                    break;
    5.96 -                }
    5.97 -            }
    5.98 -        }
    5.99 -    }
   5.100 -
   5.101 -    synchronized void ping() {
   5.102 -        if (count == 0) {
   5.103 -            Thread t = new Thread(this, "Active Reference Queue Daemon");
   5.104 -            t.setPriority(Thread.MIN_PRIORITY);
   5.105 -            t.setDaemon(true);
   5.106 -            t.start();
   5.107 -            LOGGER.fine("starting thread");
   5.108 -        } else {
   5.109 -            LOGGER.finer("enqueuing reference");
   5.110 -        }
   5.111 -        count++;
   5.112 -    }
   5.113 -}