PageRenderTime 82ms CodeModel.GetById 54ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/plugins-trunk/XML/xml/completion/CompletionInfo.java

#
Java | 314 lines | 223 code | 45 blank | 46 comment | 22 complexity | 907ab912c5fa31f23a8396ee1f23f160 MD5 | raw file
  1/*
  2 * CompletionInfo.java
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2001, 2003 Slava Pestov
  7 *
  8 * The XML plugin is licensed under the GNU General Public License, with
  9 * the following exception:
 10 *
 11 * "Permission is granted to link this code with software released under
 12 * the Apache license version 1.1, for example used by the Xerces XML
 13 * parser package."
 14 */
 15
 16package xml.completion;
 17
 18import java.util.ArrayList;
 19import java.util.HashMap;
 20import java.util.Iterator;
 21import java.util.List;
 22import java.util.regex.Matcher;
 23import java.util.regex.Pattern;
 24import java.util.regex.PatternSyntaxException;
 25
 26import org.gjt.sp.jedit.Buffer;
 27import org.gjt.sp.jedit.MiscUtilities;
 28import org.gjt.sp.jedit.jEdit;
 29import org.gjt.sp.util.Log;
 30import org.gjt.sp.util.StandardUtilities;
 31import org.xml.sax.SAXException;
 32import org.xml.sax.XMLReader;
 33//}}}
 34
 35public class CompletionInfo
 36{
 37	public ArrayList<ElementDecl> elements;
 38	public HashMap<String, ElementDecl> elementHash;
 39	public ArrayList<EntityDecl> entities;
 40	/** Appears to implement a bidirectional relationship? */
 41	public HashMap entityHash;
 42	
 43	public ArrayList elementsAllowedAnywhere;
 44
 45	/** namespace for this completion info */
 46	public String namespace;
 47	
 48	public boolean nameConflict;
 49	
 50	//{{{ CompletionInfo constructor
 51	public CompletionInfo()
 52	{
 53		this(new ArrayList<ElementDecl>(), new HashMap<String, ElementDecl>(),
 54			new ArrayList<EntityDecl>(), new HashMap(),
 55			new ArrayList());
 56
 57		addEntity(EntityDecl.INTERNAL,"lt","<");
 58		addEntity(EntityDecl.INTERNAL,"gt",">");
 59		addEntity(EntityDecl.INTERNAL,"amp","&");
 60		addEntity(EntityDecl.INTERNAL,"quot","\"");
 61		addEntity(EntityDecl.INTERNAL,"apos","'");  
 62	} //}}}
 63
 64	//{{{ CompletionInfo constructor
 65	public CompletionInfo(ArrayList<ElementDecl> elements, 
 66		HashMap<String, ElementDecl> elementHash,
 67		ArrayList<EntityDecl> entities, HashMap entityHash,
 68		ArrayList elementsAllowedAnywhere)
 69	{
 70		this.elements = elements;
 71		this.elementHash = elementHash;
 72		this.entities = entities;
 73		this.entityHash = entityHash;
 74		this.elementsAllowedAnywhere = elementsAllowedAnywhere;
 75	} //}}}
 76
 77	//{{{ addEntity() method
 78	public void addEntity(int type, String name, String value)
 79	{
 80		addEntity(new EntityDecl(type,name,value));
 81	} //}}}
 82
 83	//{{{ addEntity() method
 84	public void addEntity(int type, String name, String publicId, String systemId)
 85	{
 86		addEntity(new EntityDecl(type,name,publicId,systemId));
 87	} //}}}
 88
 89	//{{{ addEntity() method
 90	public void addEntity(EntityDecl entity)
 91	{
 92		entities.add(entity);
 93		if(entity.type == EntityDecl.INTERNAL
 94			&& entity.value.length() == 1)
 95		{
 96			Character ch = new Character(entity.value.charAt(0));
 97			entityHash.put(entity.name, ch);
 98			entityHash.put(ch, entity.name);
 99		}
100	} //}}}
101
102	//{{{ addElement() method
103	public void addElement(ElementDecl element)
104	{
105		elementHash.put(element.name,element);
106		elements.add(element);
107	} //}}}
108
109	//{{{ getAllElements() method
110	public void getAllElements(List<ElementDecl> out)
111	{
112		// only look for global elements, so use elementHash instead of elements
113		for(ElementDecl decl: elementHash.values())
114		{
115			if (decl.isAbstract()) 
116			{
117				List<ElementDecl> repls = decl.findReplacements();
118				out.addAll(repls);
119				
120				
121			}
122			else out.add(decl);
123		}
124	} //}}}
125
126	//{{{ getElementDeclLocal(CompletionInfo, localName) method
127	/**
128	 * @return the first declaration (global or local) found for localName
129	 *         or null
130	 */
131	public ElementDecl getElementDeclLocal(String localName)
132	{
133		// resorting to the first one in all declarations,
134		// even if it's the wrong one
135		for(ElementDecl e: elements){
136			if(localName.equals(e.name)){
137				return e;
138			}
139		}
140		return null;
141	}
142	//}}}
143
144
145	//{{{ toString() method
146	public String toString()
147	{
148		StringBuffer buf = new StringBuffer();
149
150		buf.append("<element-list>\n\n");
151
152		for(int i = 0; i < elements.size(); i++)
153		{
154			buf.append(elements.get(i));
155			buf.append('\n');
156		}
157
158		buf.append("\n</element-list>\n\n<entity-list>\n\n");
159
160		buf.append("<!-- not implemented yet -->\n");
161		/* for(int i = 0; i < entities.size(); i++)
162		{
163			buf.append(entities.get(i));
164			buf.append('\n');
165		} */
166
167		buf.append("\n</entity-list>");
168
169		return buf.toString();
170	} //}}}
171
172	//{{{ getCompletionInfoForBuffer() method
173	public static CompletionInfo getCompletionInfoForBuffer(Buffer buffer)
174	{
175		Iterator iter = globs.keySet().iterator();
176		while(iter.hasNext())
177		{
178			Pattern re = (Pattern) iter.next();
179			Matcher m = re.matcher(buffer.getName());
180			if(m.matches())
181				return getCompletionInfoFromResource((String)globs.get(re));
182		}
183
184		String resource = jEdit.getProperty("mode."
185			+ buffer.getMode().getName()
186			+ ".xml.completion-info");
187		if(resource != null)
188		{
189			CompletionInfo info = getCompletionInfoFromResource(resource);
190
191			if(info != null)
192				return info;
193		}
194
195		return null;
196	} //}}}
197
198	//{{{ getCompletionInfoForNamespace() method
199	public static CompletionInfo getCompletionInfoForNamespace(String namespace)
200	{
201		synchronized(lock)
202		{
203			Object obj = completionInfoNamespaces.get(namespace);
204			if(obj instanceof String)
205			{
206				CompletionInfo info = getCompletionInfoFromResource((String)obj);
207				info.namespace = namespace;
208				completionInfoNamespaces.put(namespace, info);
209				return info;
210			}
211			else
212				return (CompletionInfo)obj;
213		}
214	} //}}}
215
216	//{{{ getCompletionInfoFromResource() method
217	public static CompletionInfo getCompletionInfoFromResource(String resource)
218	{
219		synchronized(lock)
220		{
221			CompletionInfo info = (CompletionInfo)completionInfoResources.get(resource);
222			if(info != null)
223				return info;
224
225			Log.log(Log.DEBUG,CompletionInfo.class,"Loading " + resource);
226
227			CompletionInfoHandler handler = new CompletionInfoHandler();
228
229			try
230			{
231				XMLReader parser = new org.apache.xerces.parsers.SAXParser();
232				parser.setFeature("http://apache.org/xml/features/validation/dynamic",true);
233				parser.setFeature("http://xml.org/sax/features/use-entity-resolver2", true);
234				parser.setErrorHandler(handler);
235				parser.setEntityResolver(handler);
236				parser.setContentHandler(handler);
237				parser.parse(resource);
238			}
239			catch(SAXException se)
240			{
241				Throwable e = se.getException();
242				if(e == null)
243					e = se;
244				Log.log(Log.ERROR,CompletionInfo.class,e);
245			}
246			catch(Exception e)
247			{
248				Log.log(Log.ERROR,CompletionInfo.class,e);
249			}
250
251			info = handler.getCompletionInfo();
252			completionInfoResources.put (resource, info);
253
254			return info;
255		}
256	} //}}}
257
258	//{{{ clone() method
259	public Object clone()
260	{
261		return new CompletionInfo(
262			(ArrayList)elements.clone(),
263			(HashMap)elementHash.clone(),
264			(ArrayList)entities.clone(),
265			(HashMap)entityHash.clone(),
266			(ArrayList)elementsAllowedAnywhere.clone()
267		);
268	} //}}}
269
270	//{{{ Private members
271	private static HashMap<Pattern, String> globs;
272	private static HashMap<String, CompletionInfo> completionInfoResources;
273	private static HashMap<String, Object> completionInfoNamespaces;
274	private static Object lock;
275
276	//{{{ Class initializer
277	static
278	{
279		completionInfoResources = new HashMap<String, CompletionInfo>();
280		globs = new HashMap<Pattern, String>();
281		int i = 0;
282		String glob;
283		while((glob = jEdit.getProperty("xml.completion.glob." + i + ".key")) != null)
284		{
285			String info = jEdit.getProperty("xml.completion.glob." + i + ".value");
286			try
287			{
288				globs.put(Pattern.compile(StandardUtilities.globToRE(glob),
289					Pattern.CASE_INSENSITIVE), info);
290			}
291			catch(PatternSyntaxException pse)
292			{
293				Log.log(Log.ERROR,CompletionInfo.class,pse);
294			}
295
296			i++;
297		}
298
299		completionInfoNamespaces = new HashMap<String, Object>();
300		i = 0;
301		String namespace;
302		while((namespace = jEdit.getProperty("xml.completion.namespace." + i + ".key")) != null)
303		{
304			String info = jEdit.getProperty("xml.completion.namespace." + i + ".value");
305			completionInfoNamespaces.put(namespace, info);
306
307			i++;
308		}
309
310		lock = new Object();
311	} //}}}
312
313	//}}}
314}