1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package com.sun.star.script.framework.container;
24 
25 import java.io.File;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.io.FileInputStream;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.FileNotFoundException;
32 import java.io.ByteArrayInputStream;
33 
34 import java.util.ArrayList;
35 import java.util.Map;
36 import java.util.HashMap;
37 import java.util.Hashtable;
38 import java.util.Enumeration;
39 import java.util.Iterator;
40 
41 // import javax.xml.parsers.DocumentBuilderFactory;
42 // import javax.xml.parsers.DocumentBuilder;
43 // import javax.xml.parsers.ParserConfigurationException;
44 
45 import org.w3c.dom.*;
46 
47 public class ParcelDescriptor {
48 
49     // File name to be used for parcel descriptor files
50     public static final String
51         PARCEL_DESCRIPTOR_NAME = "parcel-descriptor.xml";
52 
53     // Collection of all ParcelDescriptor created for files
54     private static final Map PARCEL_DESCRIPTOR_MAP = new HashMap(5);
55 
56     // This is the default contents of a parcel descriptor to be used when
57     // creating empty descriptors
58     private static final byte[] EMPTY_DOCUMENT =
59         ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
60          "<parcel xmlns:parcel=\"scripting.dtd\" language=\"Java\">\n" +
61          "</parcel>").getBytes();
62 
63     private File file = null;
64     private Document document = null;
65     private String language = null;
66     private Map languagedepprops = new Hashtable(3);
67 
removeParcelDescriptor(File parent)68     public static synchronized void removeParcelDescriptor(File parent) {
69         File path = new File(parent, PARCEL_DESCRIPTOR_NAME);
70         PARCEL_DESCRIPTOR_MAP.remove(path);
71     }
72 
renameParcelDescriptor(File oldFile, File newFile)73     public static synchronized void renameParcelDescriptor(File oldFile, File newFile) {
74         File oldPath = new File(oldFile, PARCEL_DESCRIPTOR_NAME);
75         ParcelDescriptor pd = (ParcelDescriptor)PARCEL_DESCRIPTOR_MAP.get(oldPath);
76         if(pd != null) {
77             PARCEL_DESCRIPTOR_MAP.remove(oldPath);
78             File newPath = new File(newFile, PARCEL_DESCRIPTOR_NAME);
79             pd.file = newPath;
80             PARCEL_DESCRIPTOR_MAP.put(newPath, pd);
81         }
82     }
83 
84     // returns the ParcelDescriptor in the corresponding directory
85     // returns null if no ParcelDescriptor is found in the directory
86     public static synchronized ParcelDescriptor
getParcelDescriptor(File parent)87         getParcelDescriptor(File parent) {
88 
89         File path = new File(parent, PARCEL_DESCRIPTOR_NAME);
90         ParcelDescriptor pd = (ParcelDescriptor)PARCEL_DESCRIPTOR_MAP.get(path);
91 
92         if (pd == null && path.exists()) {
93             try {
94                 pd = new ParcelDescriptor(path);
95             }
96             catch (IOException ioe) {
97                 return null;
98             }
99             PARCEL_DESCRIPTOR_MAP.put(path, pd);
100         }
101         return pd;
102     }
103 
104     // returns a ParcelDescriptor for the corresponding directory
105     // if no ParcelDescriptor exists, one is created
106     public static synchronized ParcelDescriptor
createParcelDescriptor(File parent)107         createParcelDescriptor(File parent) throws IOException {
108 
109         ParcelDescriptor pd = getParcelDescriptor(parent);
110 
111         if (pd == null) {
112             if (parent == null || !parent.exists() || !parent.isDirectory()) {
113                 throw new IOException("Cannot create Parcel Descriptor");
114             }
115 
116             File path = new File(parent, PARCEL_DESCRIPTOR_NAME);
117             pd = new ParcelDescriptor(path);
118             PARCEL_DESCRIPTOR_MAP.put(path, pd);
119         }
120         return pd;
121     }
122 
ParcelDescriptor()123     public ParcelDescriptor() throws IOException {
124         ByteArrayInputStream bis = null;
125         try {
126             bis = new ByteArrayInputStream(EMPTY_DOCUMENT);
127             this.document = XMLParserFactory.getParser().parse(bis);
128         }
129         finally {
130             if (bis != null)
131                 bis.close();
132         }
133     }
134 
ParcelDescriptor(Document document)135     public ParcelDescriptor(Document document) {
136         this.document = document;
137         initLanguageProperties();
138     }
139 
ParcelDescriptor(InputStream is)140     public ParcelDescriptor(InputStream is) throws IOException {
141         this(XMLParserFactory.getParser().parse(is));
142     }
143 
ParcelDescriptor(File file)144     public ParcelDescriptor(File file) throws IOException {
145         this(file, "Java");
146     }
147 
ParcelDescriptor(File file, String language)148     public ParcelDescriptor(File file, String language) throws IOException {
149         this.file = file;
150 
151         if (file.exists()) {
152             FileInputStream fis = null;
153             try {
154                 fis = new FileInputStream(file);
155                 this.document = XMLParserFactory.getParser().parse(fis);
156             }
157             finally {
158                 if (fis != null)
159                     fis.close();
160             }
161         }
162         else {
163             ByteArrayInputStream bis = null;
164             try {
165                 bis = new ByteArrayInputStream(EMPTY_DOCUMENT);
166                 this.document = XMLParserFactory.getParser().parse(bis);
167             }
168             finally {
169                 if (bis != null)
170                     bis.close();
171             }
172             setLanguage(language);
173         }
174         initLanguageProperties();
175     }
176 
write(File file)177     public void write(File file) throws IOException {
178         FileOutputStream fos = new FileOutputStream(file);
179         XMLParserFactory.getParser().write(document, fos);
180         fos.close();
181     }
182 
write()183     public void write() throws IOException {
184         if (file == null)
185             throw new FileNotFoundException("No file specified");
186 
187         write(file);
188     }
189 
write(OutputStream out)190     public void write(OutputStream out) throws IOException {
191         XMLParserFactory.getParser().write(document, out);
192     }
193 
getDocument()194     public Document getDocument() {
195         return document;
196     }
197 
getLanguage()198     public String getLanguage() {
199         if (language == null) {
200             if (document != null) {
201                 Element e = document.getDocumentElement();
202                 language = e.getAttribute("language");
203             }
204         }
205         return language;
206     }
207 
setLanguage(String language)208     public void setLanguage(String language) {
209         this.language = language;
210 
211         if (document != null) {
212             try {
213                 Element e = document.getDocumentElement();
214                 e.setAttribute("language", language);
215             }
216             catch (DOMException de) {
217             }
218         }
219     }
220 
getScriptEntries()221     public ScriptEntry[] getScriptEntries() {
222         ArrayList scripts = new ArrayList();
223         NodeList scriptNodes;
224         int len;
225 
226         if (document == null ||
227             (scriptNodes = document.getElementsByTagName("script")) == null ||
228             (len = scriptNodes.getLength()) == 0)
229             return new ScriptEntry[0];
230 
231         for (int i = 0; i < len; i++) {
232             String language, languagename, logicalname, description = "";
233             Map langProps = new HashMap();
234             NodeList nl;
235             Element tmp;
236 
237             Element scriptElement = (Element)scriptNodes.item(i);
238             language = scriptElement.getAttribute("language");
239 
240             nl = scriptElement.getElementsByTagName("logicalname");
241             if (nl == null)
242                 logicalname = "";
243             else {
244                 tmp = (Element)nl.item(0);
245                 logicalname = tmp.getAttribute("value");
246             }
247 
248             // get the text of the description element
249             nl = scriptElement.getElementsByTagName("locale");
250             if (nl != null)
251             {
252                 nl = nl.item(0).getChildNodes();
253                 if (nl != null)
254                 {
255                     for (int j = 0 ; j < nl.getLength(); j++)
256                     {
257                         if (nl.item(j).getNodeName().equals("description"))
258                         {
259                             CharacterData cd =
260                                 (CharacterData)nl.item(j).getFirstChild();
261                             description = cd.getData().trim();
262                         }
263                     }
264                 }
265             }
266 
267             nl = scriptElement.getElementsByTagName("functionname");
268             if (nl == null) {
269                 languagename = "";
270             } else {
271                 tmp = (Element)nl.item(0);
272                 languagename = tmp.getAttribute("value");
273             }
274             nl = scriptElement.getElementsByTagName("languagedepprops");
275             if ( nl != null && nl.getLength() > 0 )
276             {
277 
278                 NodeList props = ((Element)nl.item(0)).getElementsByTagName("prop");
279                 if ( props != null )
280                 {
281                     for ( int j=0; j < props.getLength(); j++ )
282                     {
283                         tmp = (Element)props.item(j);
284                         String key = tmp.getAttribute("name");
285                         String val = tmp.getAttribute("value");
286                         langProps.put( key,val );
287                     }
288                 }
289             }
290             ScriptEntry entry = new ScriptEntry(language, languagename, logicalname, "",langProps, description);
291             scripts.add(entry);
292         }
293         return (ScriptEntry[])scripts.toArray(new ScriptEntry[0]);
294     }
295 
setScriptEntries(ScriptEntry[] scripts)296     public void setScriptEntries(ScriptEntry[] scripts) {
297         clearEntries();
298         for (int i = 0; i < scripts.length; i++)
299             addScriptEntry(scripts[i]);
300     }
301 
setScriptEntries(Enumeration scripts)302     public void setScriptEntries(Enumeration scripts) {
303         clearEntries();
304         while (scripts.hasMoreElements())
305             addScriptEntry((ScriptEntry) scripts.nextElement());
306     }
307 
getLanguageProperty(String name)308     public String getLanguageProperty(String name) {
309         return (String)languagedepprops.get(name);
310     }
311 
setLanguageProperty(String name, String value)312     public void setLanguageProperty(String name, String value) {
313         languagedepprops.put(name, value);
314         setScriptEntries(getScriptEntries());
315     }
316 
initLanguageProperties()317     private void initLanguageProperties() {
318         NodeList nl = document.getElementsByTagName("languagedepprops");
319         int len;
320 
321         if (nl != null && (len = nl.getLength()) != 0) {
322 
323             for (int i = 0; i < len; i++) {
324                 Element e = (Element)nl.item(i);
325                 NodeList nl2 = e.getElementsByTagName("prop");
326                 int len2;
327 
328                 if (nl2 != null && (len2 = nl2.getLength()) != 0) {
329                     for (int j = 0; j < len2; j++) {
330                         Element e2 = (Element)nl2.item(j);
331 
332                         String name = e2.getAttribute("name");
333                         String value = e2.getAttribute("value");
334 
335                         if (getLanguageProperty(name) == null) {
336                             languagedepprops.put(name, value);
337                         }
338                     }
339                 }
340             }
341         }
342     }
343 
clearEntries()344     private void clearEntries() {
345         NodeList scriptNodes;
346         Element main = document.getDocumentElement();
347         int len;
348 
349         if ((scriptNodes = document.getElementsByTagName("script")) != null &&
350             (len = scriptNodes.getLength()) != 0)
351         {
352             for (int i = len - 1; i >= 0; i--) {
353                 try {
354                     main.removeChild(scriptNodes.item(i));
355                 }
356                 catch (DOMException de) {
357                     // ignore
358                 }
359             }
360         }
361     }
362 
removeScriptEntry(ScriptEntry script)363     public void removeScriptEntry(ScriptEntry script) {
364         NodeList scriptNodes;
365         Element main = document.getDocumentElement();
366         int len;
367 
368         if ((scriptNodes = document.getElementsByTagName("script")) != null &&
369             (len = scriptNodes.getLength()) != 0)
370         {
371             for (int i = len - 1; i >= 0; i--) {
372                 try {
373                     Element scriptElement = (Element)scriptNodes.item(i);
374                     String languagename = "";
375 
376                     NodeList nl =
377                         scriptElement.getElementsByTagName("functionname");
378                     if (nl == null) {
379                         continue;
380                     } else {
381                         Element tmp = (Element)nl.item(0);
382                         languagename = tmp.getAttribute("value");
383                     }
384 
385                     if (languagename.equals(script.getLanguageName())) {
386                         main.removeChild(scriptElement);
387                     }
388                 }
389                 catch (DOMException de) {
390                     // ignore
391                 }
392             }
393         }
394     }
395 
addScriptEntry(ScriptEntry script)396     public void addScriptEntry(ScriptEntry script) {
397         Element main = document.getDocumentElement();
398         Element root, item, tempitem;
399 
400         root = document.createElement("script");
401         root.setAttribute("language", script.getLanguage());
402 
403         item = document.createElement("locale");
404         item.setAttribute("lang", "en");
405         tempitem = document.createElement("displayname");
406         tempitem.setAttribute("value", script.getLogicalName());
407         item.appendChild(tempitem);
408 
409         tempitem = document.createElement("description");
410         String description = script.getDescription();
411         if (description == null || description.equals(""))
412         {
413             description = script.getLogicalName();
414         }
415         tempitem.appendChild(document.createTextNode(description));
416         item.appendChild(tempitem);
417 
418         root.appendChild(item);
419 
420         item = document.createElement("logicalname");
421         item.setAttribute("value", script.getLogicalName());
422         root.appendChild(item);
423 
424         item = document.createElement("functionname");
425         item.setAttribute("value", script.getLanguageName());
426         root.appendChild(item);
427 
428         if (languagedepprops != null && languagedepprops.size() != 0) {
429             String key;
430             item = document.createElement("languagedepprops");
431 
432             Iterator iter = languagedepprops.keySet().iterator();
433             while (iter.hasNext()) {
434                 tempitem = document.createElement("prop");
435                 key = (String)iter.next();
436                 tempitem.setAttribute("name", key);
437                 tempitem.setAttribute("value", (String)languagedepprops.get(key));
438                 item.appendChild(tempitem);
439             }
440             root.appendChild(item);
441         }
442 
443         //add to the Top Element
444         main.appendChild(root);
445     }
446 }
447