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 
24 package com.sun.star.script.framework.container;
25 
26 import java.net.URL;
27 
28 import java.io.ByteArrayInputStream;
29 
30 import java.util.Vector;
31 import java.util.StringTokenizer;
32 
33 import java.io.InputStream;
34 import java.io.OutputStream;
35 
36 import com.sun.star.script.framework.log.LogUtils;
37 
38 import com.sun.star.script.framework.provider.PathUtils;
39 
40 import com.sun.star.script.framework.io.XInputStreamImpl;
41 
42 import com.sun.star.script.framework.container.ScriptEntry;
43 import com.sun.star.script.framework.container.Parcel;
44 
45 import com.sun.star.script.framework.io.UCBStreamHandler;
46 
47 import com.sun.star.ucb.XSimpleFileAccess2;
48 
49 import com.sun.star.uno.UnoRuntime;
50 
51 public class ScriptMetaData extends ScriptEntry implements Cloneable {
52     private boolean hasSource = false;
53     private String locationPlaceHolder = "";
54     private String source;
55     private Parcel parent;
56 
57 
ScriptMetaData( Parcel parent, ScriptEntry entry, String source )58     public ScriptMetaData( Parcel parent, ScriptEntry entry,
59                            String source )
60     {
61         super( entry );
62         this.parent = parent;
63         if ( source != null )
64         {
65             this.hasSource = true;
66             this.source = source;
67         }
68 
69     }
70 
hasSource()71     public boolean hasSource()
72     {
73         return hasSource;
74     }
getSource()75     public String getSource()
76     {
77 
78         if ( source !=null && hasSource )
79         {
80             return source;
81         }
82         else
83         {
84             return null;
85         }
86     }
87 
getSourceBytes()88     public byte[] getSourceBytes()
89     {
90         if ( source !=null && hasSource )
91         {
92             return source.getBytes();
93         }
94         else
95         {
96             return null;
97         }
98 
99     }
clone()100     public Object clone() throws CloneNotSupportedException {
101         return super.clone();
102     }
103 
equals(ScriptMetaData other)104     public boolean equals(ScriptMetaData other) {
105         if (super.equals(other) &&
106             hasSource == other.hasSource() )
107         {
108             return true;
109         }
110         return false;
111     }
112 
getScriptFullURL()113     public String getScriptFullURL()
114     {
115         String url = "vnd.sun.star.script:" + parent.getName() + "." + getLanguageName() +
116             "?" + "language=" + getLanguage() +
117             "&location=" + getParcelLocation();
118          return url;
119     }
120 
getShortFormScriptURL()121     public String getShortFormScriptURL()
122     {
123         String url = "vnd.sun.star.script:" + parent.getName() + "." + getLanguageName() +
124             "?" + "language=" + getLanguage() +
125             "&location=" + getLocationPlaceHolder();
126         return url;
127     }
128 
129     // TODO probably should be private should not be necessary
130     // to be exposed at all
131 
132 	private static final String SHARE =
133         "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" +
134         PathUtils.BOOTSTRAP_NAME +
135         "::BaseInstallation}/share";
136 
137 	private static final String USER =
138         "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" +
139         PathUtils.BOOTSTRAP_NAME +
140         "::UserInstallation}/user";
141 
142 	private static final String UNO_USER_PACKAGES1 =
143         "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE";
144 
145 	private static final String UNO_USER_PACKAGES2 =
146         USER + "/uno_packages";
147 
148 	private static final String UNO_SHARED_PACKAGES1 =
149         "$UNO_SHARED_PACKAGES_CACHE";
150 
151 	private static final String UNO_SHARED_PACKAGES2 =
152         SHARE + "/uno_packages";
153 
getLocationPlaceHolder(String url, String pkgname)154     public static String getLocationPlaceHolder(String url, String pkgname)
155 	{
156         String result = "Unknown";
157 
158         if ( url.indexOf(UNO_USER_PACKAGES1) > -1 ||
159              url.indexOf(UNO_USER_PACKAGES2) > -1 )
160         {
161             result = PathUtils.make_url( "user:uno_packages", pkgname );
162         }
163         else if ( url.indexOf(UNO_SHARED_PACKAGES1) > -1 ||
164                   url.indexOf(UNO_SHARED_PACKAGES2) > -1 )
165         {
166             result = PathUtils.make_url( "share:uno_packages", pkgname );
167         }
168         else if ( url.indexOf(SHARE) == 0 )
169         {
170             result = "share";
171         }
172         else if ( url.indexOf(USER) == 0 )
173         {
174             result = "user";
175         }
176         else if ( url.indexOf("vnd.sun.star.tdoc:") == 0 )
177         {
178             result = "document";
179         }
180         return result;
181 	}
182 
getLocationPlaceHolder()183     public String getLocationPlaceHolder()
184     {
185         String placeHolder = "Unknown";
186         String pathToParcel = parent.getPathToParcel();
187 
188         if ( pathToParcel.indexOf(UNO_USER_PACKAGES1) > -1 ||
189              pathToParcel.indexOf(UNO_USER_PACKAGES2) > -1 )
190         {
191             // its a package
192             placeHolder = "user:uno_packages";
193             String unoPkg = parent.parent.getName();
194             if ( unoPkg != null )
195             {
196                 placeHolder = PathUtils.make_url( placeHolder, unoPkg );
197             }
198         }
199         else if ( pathToParcel.indexOf(UNO_SHARED_PACKAGES1) > -1 ||
200                   pathToParcel.indexOf(UNO_SHARED_PACKAGES2) > -1 )
201         {
202             //its a package
203             placeHolder = "share:uno_packages";
204             String unoPkg = parent.parent.getName();
205             if ( unoPkg != null )
206             {
207                 placeHolder = PathUtils.make_url( placeHolder, unoPkg );
208             }
209         }
210         else if ( pathToParcel.indexOf(SHARE) == 0 )
211         {
212             placeHolder = "share";
213         }
214         else if ( pathToParcel.indexOf(USER) == 0 )
215         {
216             placeHolder = "user";
217         }
218         else if ( pathToParcel.indexOf("vnd.sun.star.tdoc:") == 0 )
219         {
220             placeHolder = "document";
221         }
222         // TODO handling document packages ??? not really sure of package url
223 /*        else
224         {
225         } */
226         return placeHolder;
227     }
228 
229     // TODO probably should be private should not be necessary
230     // to be exposed at all only used in lang providers at the moment
231     // to generate URL for script, editors should use a model of script
232     // source and not interact with the URL
233     // Also if it is to remain needs to be renamed to getParcelLocationURL
234 
235     // return  URL string  to parcel
getParcelLocation()236     public String getParcelLocation()
237     {
238         return parent.getPathToParcel();
239     }
240 
241 
toString()242     public String toString()
243     {
244         return "\nParcelLocation = " + getParcelLocation() + "\nLocationPlaceHolder = " + locationPlaceHolder + super.toString();
245     }
246 
getClassPath()247     public URL[] getClassPath() throws java.net.MalformedURLException
248     {
249     try
250     {
251         String classpath = (String)getLanguageProperties().get("classpath");
252         Vector paths = null;
253 
254         if ( classpath == null )
255         {
256             classpath = "";
257         }
258 
259         String parcelPath = getParcelLocation();
260         // make sure path ends with /
261         if ( !parcelPath.endsWith("/") )
262         {
263             parcelPath += "/";
264         }
265 
266         // replace \ with /
267         parcelPath = parcelPath.replace( '\\', '/' );
268 
269         Vector classPathVec =  new Vector();
270         StringTokenizer stk = new StringTokenizer(classpath, ":");
271         while (  stk.hasMoreElements() )
272         {
273             String relativeClasspath =  (String)stk.nextElement();
274             String pathToProcess  = PathUtils.make_url( parcelPath, relativeClasspath);
275             URL url = createURL( pathToProcess );
276             if ( url != null )
277             {
278                 classPathVec.add (  url  );
279             }
280 
281         }
282         if ( classPathVec.size() == 0)
283         {
284             URL url = createURL( parcelPath );
285             if ( url != null )
286             {
287                 classPathVec.add(url);
288             }
289         }
290 
291         return  (URL[])classPathVec.toArray( new URL[0]);
292     }
293     catch ( Exception e )
294     {
295         LogUtils.DEBUG("Failed to build class path " + e.toString() );
296         LogUtils.DEBUG( LogUtils.getTrace( e ) );
297         return new URL[0];
298     }
299 
300     }
createURL( String path )301     private URL createURL( String path ) throws java.net.MalformedURLException
302     {
303         URL url = null;
304         int indexOfColon = path.indexOf(":");
305         String scheme = path.substring( 0, indexOfColon );
306         UCBStreamHandler handler = new UCBStreamHandler( parent.parent.m_xCtx, scheme, parent.m_xSFA);
307 
308         path += UCBStreamHandler.separator;
309         url = new URL(null, path, handler);
310         return url;
311     }
312 
313     // TODO should decide whether this should throw or not
314     // decide whether it should be public or protected ( final ? )
loadSource()315     public void loadSource()
316     {
317             try
318             {
319                 URL sourceUrl = getSourceURL();
320                 LogUtils.DEBUG("** In load source BUT not loading yet for " + sourceUrl );
321 
322                 if ( sourceUrl != null )
323                 {
324                     StringBuffer buf = new StringBuffer();
325                     InputStream in = sourceUrl.openStream();
326 
327                     byte[] contents = new byte[1024];
328                     int len = 0;
329 
330                     while ((len = in.read(contents, 0, 1024)) != -1) {
331                         buf.append(new String(contents, 0, len));
332                     }
333 
334                     try {
335                         in.close();
336                     }
337                     catch (java.io.IOException ignore ) {
338                         LogUtils.DEBUG("** Failed to read scriot from url " + ignore.toString() );
339                     }
340 
341                     source = buf.toString();
342                     hasSource = true;
343                 }
344             }
345             catch (java.io.IOException e) {
346                 LogUtils.DEBUG("** Failed to read scriot from url " + e.toString());
347             }
348 
349         }
writeSourceFile()350     protected boolean writeSourceFile()
351     {
352         String parcelLocation = parent.getPathToParcel();
353         String sourceFilePath = parent.getPathToParcel() + "/" + getLanguageName();
354         boolean result = false;
355         OutputStream os = null;
356         try
357         {
358             XSimpleFileAccess2 xSFA2 = ( XSimpleFileAccess2 )
359                 UnoRuntime.queryInterface( XSimpleFileAccess2.class,
360                     parent.m_xSFA );
361             if ( xSFA2 != null )
362             {
363                 ByteArrayInputStream bis = new ByteArrayInputStream( getSourceBytes() );
364                 XInputStreamImpl xis = new XInputStreamImpl( bis );
365                 xSFA2.writeFile( sourceFilePath, xis );
366                 xis.closeInput();
367                 result = true;
368             }
369         }
370         // TODO re-examine exception processing should probably throw
371         // exceptions back to caller
372         catch ( Exception ignore )
373 
374         {
375         }
376         return result;
377     }
removeSourceFile()378     protected boolean removeSourceFile()
379     {
380         String parcelLocation = parent.getPathToParcel();
381         String sourceFilePath = parcelLocation + "/" + getLanguageName();
382         boolean result = false;
383         try
384         {
385             parent.m_xSFA.kill( sourceFilePath );
386             result = true;
387         }
388         // TODO reexamine exception handling
389         catch ( Exception e )
390         {
391         }
392         return result;
393     }
394 
getSourceURL()395     public URL getSourceURL() throws java.net.MalformedURLException
396     {
397         String sUrl = null;
398         URL scriptURL = null;
399 
400         sUrl = getParcelLocation();
401         sUrl = PathUtils.make_url( sUrl, getLanguageName() );
402         LogUtils.DEBUG("Creating script url for " + sUrl );
403         scriptURL = createURL( sUrl );
404         return scriptURL;
405     }
406 }
407