KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > api > model > GrammarQueryManager


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.api.model;
21
22 import java.beans.FeatureDescriptor JavaDoc;
23 import java.io.PrintWriter JavaDoc;
24 import java.io.StringWriter JavaDoc;
25 import java.lang.ref.Reference JavaDoc;
26 import java.lang.ref.WeakReference JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import org.netbeans.modules.xml.api.model.GrammarQuery;
31 import org.openide.ErrorManager;
32 import org.openide.filesystems.FileObject;
33 import org.openide.filesystems.FileSystem;
34 import org.openide.filesystems.Repository;
35 import org.openide.loaders.DataObject;
36 import org.openide.loaders.DataObjectNotFoundException;
37 import org.openide.loaders.FolderLookup;
38 import org.openide.util.Lookup;
39 import org.xml.sax.InputSource JavaDoc;
40
41 /**
42  * GrammarQuery service provider definition. Manager methods
43  * are interleated and client must invoke them in particular
44  * sequence from single thread to get desired results:
45  * <pre>
46  * enabledFor = manager.enabled(context);
47  * if (enabled != null) {
48  * grammar = manager.getGrammar(context);
49  * //... guard enableness and enjoy the grammar
50  * }
51  * </pre>
52  *
53  * @author Petr Kuzel
54  */

55 public abstract class GrammarQueryManager {
56
57     // default instance
58
private static Reference JavaDoc instance;
59     
60     /**
61      * Can this manager provide a grammar for given context?
62      * @param ctx GrammarEnvironment describing grammar context.
63      * @return <code>null</code> if a grammar cannot be provided for
64      * the context else return context items (subenum of
65      * <code>ctx.getDocumentChildren</code>) that defines
66      * grammar enableness context.
67      */

68     public abstract Enumeration JavaDoc enabled(GrammarEnvironment ctx);
69     
70     /**
71      * Factory method providing a root grammar for given document.
72      * @param ctx The same context that was passed to {@link #enabled}.
73      * @return GrammarQuery being able to work in the context
74      * or <code>null</code> if {@link #enabled} returns
75      * for the same context false.
76      */

77     public abstract GrammarQuery getGrammar(GrammarEnvironment ctx);
78     
79     /**
80      * @return detailed description.
81      */

82     public abstract FeatureDescriptor JavaDoc getDescriptor();
83     
84     /**
85      * A factory method looking for subclasses registered in Lookup
86      * under <code>Plugins/XML/GrammarQueryManagers</code>.
87      * <p>
88      * There are defined some ordering marks to which every registration
89      * must express its position:
90      * <code>semantics-grammar-to-generic-grammar-separator</code>.
91      * All generic grammars such as universal DTD and XML Schema grammar
92      * must be behing this mark. Semantics grammars such as
93      * XSLT only handling grammar must be placed before it.
94      * <code>generic-grammar-to-universal-grammar-separator</code>
95      * allows to distingwish between generic grammars and universal
96      * ones (e.g. a grammar that scans well-formed document and
97      * using heuritics methods it tries to guess actual grammar on fly).
98      *
99      * @return Best effort instance.
100      */

101     public static synchronized GrammarQueryManager getDefault() {
102         Object JavaDoc cached = instance != null ? instance.get() : null;
103         if (cached == null) {
104             cached = new DefaultQueryManager();
105             instance = new WeakReference JavaDoc(cached);
106         }
107         return (GrammarQueryManager) cached;
108     }
109
110     /**
111      * Delegating implementation.
112      */

113     private static class DefaultQueryManager extends GrammarQueryManager {
114
115         private static final String JavaDoc FOLDER = "Plugins/XML/GrammarQueryManagers";// NOI18N
116

117         private Lookup.Result registrations;
118         
119         private static ThreadLocal JavaDoc transaction = new ThreadLocal JavaDoc();
120         
121         public FeatureDescriptor JavaDoc getDescriptor() {
122             FeatureDescriptor JavaDoc desc = new FeatureDescriptor JavaDoc();
123             desc.setHidden(true);
124             desc.setName(getClass().getName());
125             return desc;
126         }
127         
128         public GrammarQuery getGrammar(GrammarEnvironment ctx) {
129             try {
130                 GrammarQueryManager g = (GrammarQueryManager) transaction.get();
131                 if (g != null) {
132                     GrammarQuery query = g.getGrammar(ctx);
133                     if (query == null) {
134                         ErrorManager err = ErrorManager.getDefault();
135                         err.log(err.WARNING, "Broken contract: " + g.getClass());
136                     }
137                     return query;
138                 } else {
139                     ErrorManager err = ErrorManager.getDefault();
140                     Exception JavaDoc ex = new IllegalStateException JavaDoc("Broken contract");
141                     StringWriter JavaDoc stringWriter = new StringWriter JavaDoc();
142                     PrintWriter JavaDoc writer = new PrintWriter JavaDoc(stringWriter);
143                     ex.printStackTrace(writer);
144                     writer.flush();
145                     err.log(err.WARNING, stringWriter.getBuffer().toString());
146                     return null;
147                 }
148             } finally {
149                 transaction.set(null);
150             }
151         }
152         
153         public Enumeration JavaDoc enabled(GrammarEnvironment ctx) {
154             Iterator JavaDoc it = getRegistrations();
155             transaction.set(null);
156             ArrayList JavaDoc list = new ArrayList JavaDoc(5);
157             {
158                 Enumeration JavaDoc en = ctx.getDocumentChildren();
159                 while (en.hasMoreElements()) {
160                     list.add(en.nextElement());
161                 }
162             }
163             Object JavaDoc[] array = list.toArray();
164             while (it.hasNext()) {
165                 GrammarQueryManager next = (GrammarQueryManager) it.next();
166                 GrammarEnvironment env = new GrammarEnvironment(
167                     org.openide.util.Enumerations.array (array),
168                     ctx.getInputSource(),
169                     ctx.getFileObject()
170                 );
171                 Enumeration JavaDoc en = next.enabled(env);
172                 if (en != null) {
173                     transaction.set(next);
174                     return en;
175                 }
176             }
177             return null;
178         }
179         
180         private synchronized Iterator JavaDoc getRegistrations() {
181             if (registrations != null) {
182                 return registrations.allInstances().iterator();
183             }
184
185             // try to initialize it
186

187             try {
188                 FileSystem fs = Repository.getDefault().getDefaultFileSystem();
189                 FileObject fo = fs.findResource(FOLDER);
190                 DataObject df = DataObject.find(fo);
191                 if (df instanceof DataObject.Container) {
192                     FolderLookup lookup =
193                         new FolderLookup((DataObject.Container) df);
194                     Lookup.Template template =
195                         new Lookup.Template(GrammarQueryManager.class);
196                     registrations = lookup.getLookup().lookup(template);
197                     return registrations.allInstances().iterator();
198                 } else {
199                     return new ArrayList JavaDoc(0).iterator();
200                 }
201             } catch (DataObjectNotFoundException ex) {
202                 return new ArrayList JavaDoc(0).iterator();
203             }
204         }
205     }
206 }
207
Popular Tags