KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > lexer > LanguageManager


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.lib.lexer;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.lang.ref.WeakReference JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.WeakHashMap JavaDoc;
31 import org.netbeans.api.lexer.InputAttributes;
32 import org.netbeans.api.lexer.Language;
33 import org.netbeans.api.lexer.LanguagePath;
34 import org.netbeans.api.lexer.Token;
35 import org.netbeans.api.lexer.TokenId;
36 import org.netbeans.spi.lexer.LanguageEmbedding;
37 import org.netbeans.spi.lexer.LanguageHierarchy;
38 import org.netbeans.spi.lexer.LanguageProvider;
39 import org.netbeans.spi.lexer.Lexer;
40 import org.netbeans.spi.lexer.LexerRestartInfo;
41 import org.openide.util.Lookup;
42 import org.openide.util.LookupEvent;
43 import org.openide.util.LookupListener;
44
45 /**
46  *
47  * @author vita
48  */

49 public final class LanguageManager extends LanguageProvider implements LookupListener, PropertyChangeListener JavaDoc {
50     
51     private static final Language<TokenId> NO_LANG = new LanguageHierarchy<TokenId>() {
52         @Override JavaDoc
53         protected Lexer<TokenId> createLexer(LexerRestartInfo<TokenId> info) {
54             return null;
55         }
56         @Override JavaDoc
57         protected Collection JavaDoc<TokenId> createTokenIds() {
58             return Collections.emptyList();
59         }
60         @Override JavaDoc
61         protected String JavaDoc mimeType() {
62             return "obscure/no-language-marker"; //NOI18N
63
}
64     }.language();
65     
66     private static final LanguageEmbedding<TokenId> NO_LANG_EMBEDDING
67             = LanguageEmbedding.create(NO_LANG, 0, 0);
68     
69     private static LanguageManager instance = null;
70     
71     public static synchronized LanguageManager getInstance() {
72         if (instance == null) {
73             instance = new LanguageManager();
74         }
75         return instance;
76     }
77     
78     private Lookup.Result<LanguageProvider> lookupResult = null;
79
80     private List JavaDoc<LanguageProvider> providers = Collections.<LanguageProvider>emptyList();
81     private HashMap JavaDoc<String JavaDoc, WeakReference JavaDoc<Language<? extends TokenId>>> langCache
82             = new HashMap JavaDoc<String JavaDoc, WeakReference JavaDoc<Language<? extends TokenId>>>();
83     private WeakHashMap JavaDoc<Token, LanguageEmbedding<? extends TokenId>> tokenLangCache
84             = new WeakHashMap JavaDoc<Token, LanguageEmbedding<? extends TokenId>>();
85     
86     private final String JavaDoc LOCK = new String JavaDoc("LanguageManager.LOCK");
87     
88     /** Creates a new instance of LanguageManager */
89     private LanguageManager() {
90         lookupResult = Lookup.getDefault().lookup(new Lookup.Template<LanguageProvider>(LanguageProvider.class));
91         lookupResult.addLookupListener(this);
92         refreshProviders();
93     }
94
95     // -------------------------------------------------------------------
96
// LanguageProvider implementation
97
// -------------------------------------------------------------------
98

99     public Language<? extends TokenId> findLanguage(String JavaDoc mimePath) {
100         synchronized(LOCK) {
101             WeakReference JavaDoc<Language<? extends TokenId>> ref = langCache.get(mimePath);
102             Language<? extends TokenId> lang = ref == null ? null : ref.get();
103             
104             if (lang == null) {
105                 for(LanguageProvider p : providers) {
106                     if (null != (lang = p.findLanguage(mimePath))) {
107                         break;
108                     }
109                 }
110                 
111                 if (lang == null) {
112                     lang = NO_LANG;
113                 }
114                 
115                 langCache.put(mimePath, new WeakReference JavaDoc<Language<? extends TokenId>>(lang));
116             }
117             
118             return lang == NO_LANG ? null : lang;
119         }
120     }
121
122     public LanguageEmbedding<? extends TokenId> findLanguageEmbedding(
123     Token<? extends TokenId> token, LanguagePath languagePath, InputAttributes inputAttributes) {
124         synchronized(LOCK) {
125             LanguageEmbedding<? extends TokenId> lang = tokenLangCache.get(token);
126             
127             if (lang == null) {
128                 for(LanguageProvider p : providers) {
129                     if (null != (lang = p.findLanguageEmbedding(token, languagePath, inputAttributes))) {
130                         break;
131                     }
132                 }
133                 
134                 if (lang == null) {
135                     lang = NO_LANG_EMBEDDING;
136                 }
137                 
138                 tokenLangCache.put(token, lang);
139             }
140             
141             return lang == NO_LANG_EMBEDDING ? null : lang;
142         }
143     }
144
145     // -------------------------------------------------------------------
146
// LookupListener implementation
147
// -------------------------------------------------------------------
148

149     public void resultChanged(LookupEvent ev) {
150         refreshProviders();
151     }
152
153     // -------------------------------------------------------------------
154
// PropertyChangeListener implementation
155
// -------------------------------------------------------------------
156

157     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
158         if (evt.getPropertyName() == null) {
159             synchronized(LOCK) {
160                 langCache.clear();
161                 tokenLangCache.clear();
162             }
163         } else if (LanguageProvider.PROP_LANGUAGE.equals(evt.getPropertyName())) {
164             synchronized(LOCK) {
165                 langCache.clear();
166             }
167         } else if (LanguageProvider.PROP_EMBEDDED_LANGUAGE.equals(evt.getPropertyName())) {
168             synchronized(LOCK) {
169                 tokenLangCache.clear();
170             }
171         }
172         // Forward firing of the property change to registered clients
173
firePropertyChange(evt.getPropertyName());
174     }
175     
176     // -------------------------------------------------------------------
177
// private implementation
178
// -------------------------------------------------------------------
179

180     private void refreshProviders() {
181         Collection JavaDoc<? extends LanguageProvider> newProviders = lookupResult.allInstances();
182         
183         synchronized(LOCK) {
184             for(LanguageProvider p : providers) {
185                 p.removePropertyChangeListener(this);
186             }
187             
188             providers = new ArrayList JavaDoc<LanguageProvider>(newProviders);
189             
190             for(LanguageProvider p : providers) {
191                 p.addPropertyChangeListener(this);
192             }
193             
194             langCache.clear();
195             tokenLangCache.clear();
196         }
197     }
198
199 }
200
Popular Tags