context/src/main/java/org/netbeans/html/context/spi/Contexts.java
author Jaroslav Tulach <jtulach@netbeans.org>
Tue, 26 Aug 2014 18:13:30 +0200
changeset 838 bdc3d696dd4a
parent 790 context/src/main/java/org/apidesign/html/context/spi/Contexts.java@30f20d9c0986
child 886 88d62267a0b5
permissions -rw-r--r--
During the API review process (bug 246133) the reviewers decided that in order to include html4j to NetBeans Platform, we need to stop using org.apidesign namespace and switch to NetBeans one. Repackaging all SPI packages into org.netbeans.html.smthng.spi.
     1 /**
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     5  *
     6  * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     7  * Other names may be trademarks of their respective owners.
     8  *
     9  * The contents of this file are subject to the terms of either the GNU
    10  * General Public License Version 2 only ("GPL") or the Common
    11  * Development and Distribution License("CDDL") (collectively, the
    12  * "License"). You may not use this file except in compliance with the
    13  * License. You can obtain a copy of the License at
    14  * http://www.netbeans.org/cddl-gplv2.html
    15  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    16  * specific language governing permissions and limitations under the
    17  * License.  When distributing the software, include this License Header
    18  * Notice in each file and include the License file at
    19  * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    20  * particular file as subject to the "Classpath" exception as provided
    21  * by Oracle in the GPL Version 2 section of the License file that
    22  * accompanied this code. If applicable, add the following below the
    23  * License Header, with the fields enclosed by brackets [] replaced by
    24  * your own identifying information:
    25  * "Portions Copyrighted [year] [name of copyright owner]"
    26  *
    27  * Contributor(s):
    28  *
    29  * The Original Software is NetBeans. The Initial Developer of the Original
    30  * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    31  *
    32  * If you wish your version of this file to be governed by only the CDDL
    33  * or only the GPL Version 2, indicate your decision by adding
    34  * "[Contributor] elects to include this software in this distribution
    35  * under the [CDDL or GPL Version 2] license." If you do not indicate a
    36  * single choice of license, a recipient has the option to distribute
    37  * your version of this file under either the CDDL, the GPL Version 2 or
    38  * to extend the choice of license to its licensees as provided above.
    39  * However, if you add GPL Version 2 code and therefore, elected the GPL
    40  * Version 2 license, then the option applies only if the new code is
    41  * made subject to such option by the copyright holder.
    42  */
    43 package org.netbeans.html.context.spi;
    44 
    45 import java.util.ServiceLoader;
    46 import net.java.html.BrwsrCtx;
    47 import org.netbeans.html.context.impl.CtxImpl;
    48 
    49 /** Factory class to assign various technologies 
    50  * to a {@link BrwsrCtx browser context}. Start with {@link #newBuilder()}
    51  * and then assign technologies with {@link Builder#register(java.lang.Class, java.lang.Object, int)}
    52  * method.
    53  *
    54  * @author Jaroslav Tulach
    55  */
    56 public final class Contexts {
    57     private Contexts() {
    58     }
    59 
    60     /** Creates new, empty builder for creation of {@link BrwsrCtx}. At the
    61      * end call the {@link Builder#build()} method to generate the context.
    62      *
    63      * @return new instance of the builder
    64      */
    65     public static Builder newBuilder() {
    66         return new Builder();
    67     }
    68 
    69     /** Seeks for the specified technology in the provided context.
    70      * 
    71      * @param <Tech> type of the technology
    72      * @param context the context to seek in 
    73      *    (previously filled with ({@link Builder#register(java.lang.Class, java.lang.Object, int)})
    74      * @param technology class that identifies the technology
    75      * @return the technology in the context or <code>null</code>
    76      */
    77     public static <Tech> Tech find(BrwsrCtx context, Class<Tech> technology) {
    78         return CtxImpl.find(context, technology);
    79     }
    80 
    81     /** Seeks {@link ServiceLoader} for all registered instances of
    82      * {@link Provider} and asks them to {@link Provider#fillContext(org.netbeans.html.context.spi.Contexts.Builder, java.lang.Class) fill
    83      * the builder}.
    84      * 
    85      * @param requestor the application class for which to find the context
    86      * @param cb the context builder to register technologies into
    87      * @return <code>true</code>, if some instances of the provider were
    88      *    found, <code>false</code> otherwise
    89      * @since 0.7.6
    90      */
    91     public static boolean fillInByProviders(Class<?> requestor, Contexts.Builder cb) {
    92         boolean found = false;
    93         ClassLoader l;
    94         try {
    95             l = requestor.getClassLoader();
    96         } catch (SecurityException ex) {
    97             l = null;
    98         }
    99         for (Provider cp : ServiceLoader.load(Provider.class, l)) {
   100             cp.fillContext(cb, requestor);
   101             found = true;
   102         }
   103         try {
   104             for (Provider cp : ServiceLoader.load(Provider.class, Provider.class.getClassLoader())) {
   105                 cp.fillContext(cb, requestor);
   106                 found = true;
   107             }
   108         } catch (SecurityException ex) {
   109             if (!found) {
   110                 throw ex;
   111             }
   112         }
   113         if (!found) {
   114             for (Provider cp : ServiceLoader.load(Provider.class)) {
   115                 cp.fillContext(cb, requestor);
   116                 found = true;
   117             }
   118         }
   119         return found;
   120     }
   121 
   122     /** Implementors of various HTML technologies should
   123      * register their implementation via <code>org.openide.util.lookup.ServiceProvider</code>, so
   124      * {@link ServiceLoader} can find them, when their JARs are included
   125      * on the classpath of the running application.
   126      *
   127      * @author Jaroslav Tulach
   128      */
   129     public static interface Provider {
   130 
   131         /** Register into the context if suitable technology is
   132          * available for the requesting class.
   133          * The provider should check if its own technology is available in current
   134          * scope (e.g. proper JDK, proper browser, etc.). The provider
   135          * can also find the right context depending on requestor's classloader, etc.
   136          * <p>
   137          * Providers should use {@link Builder} to enrich appropriately
   138          * the context.
   139          *
   140          * @param context the context builder to fill with technologies
   141          * @param requestor the application class requesting access the the HTML page
   142          * @see BrwsrCtx#findDefault(java.lang.Class)
   143          */
   144         void fillContext(Builder context, Class<?> requestor);
   145     }
   146 
   147     /** Support for providers of new {@link BrwsrCtx}. Providers of different
   148      * technologies should be of particular interest in this class. End users
   149      * designing their application with existing technologies should rather
   150      * point their attention to {@link BrwsrCtx} and co.
   151      *
   152      * @author Jaroslav Tulach
   153      */
   154     public static final class Builder {
   155         private final CtxImpl impl = new CtxImpl();
   156 
   157         Builder() {
   158         }
   159         
   160         /** Registers new technology into the context. Each technology is
   161          * exactly identified by its implementation class and can be associated
   162          * with (positive) priority. In case of presence of multiple technologies
   163          * with the same class, the one with higher lower priority takes precedence.
   164          * @param <Tech> type of technology to register
   165          * @param type the real class of the technology type
   166          * @param impl an instance of the technology class
   167          * @param position the lower position, the more important implementation 
   168          *    which will be consulted sooner when seeking for a {@link Contexts#find(net.java.html.BrwsrCtx, java.lang.Class)}
   169          *    an implementation
   170          * @return this builder
   171          */
   172         public <Tech> Builder register(Class<Tech> type, Tech impl, int position) {
   173             if (impl == null) {
   174                 return this;
   175             }
   176             if (position <= 0) {
   177                 throw new IllegalStateException();
   178             }
   179             this.impl.register(type, impl, position);
   180             return this;
   181         }
   182 
   183         /** Generates context based on values previously inserted into
   184          * this builder.
   185          *
   186          * @return new, immutable instance of {@link BrwsrCtx}
   187          */
   188         public BrwsrCtx build() {
   189             return impl.build();
   190         }
   191     }
   192 }