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  com.sun.star.script.framework.log.*;
27 import  com.sun.star.script.framework.io.*;
28 import  com.sun.star.script.framework.provider.PathUtils;
29 
30 import com.sun.star.container.*;
31 import com.sun.star.uno.Type;
32 import com.sun.star.lang.*;
33 import com.sun.star.io.*;
34 import java.io.*;
35 import java.util.*;
36 import com.sun.star.ucb.XSimpleFileAccess;
37 import com.sun.star.ucb.XSimpleFileAccess2;
38 import com.sun.star.lang.XMultiComponentFactory;
39 import com.sun.star.uno.XComponentContext;
40 import com.sun.star.uno.UnoRuntime;
41 
42 import com.sun.star.uri.XUriReference;
43 import com.sun.star.uri.XUriReferenceFactory;
44 import com.sun.star.uri.XVndSunStarScriptUrl;
45 
46 /**
47  * The <code>ParcelContainer</code> object is used to store the
48  * ScripingFramework specific Libraries.
49  *
50  * @author
51  * @created
52  */
53 
54 public class ParcelContainer implements XNameAccess
55 {
56     protected String language;
57     protected String containerUrl;
58     protected Collection parcels = new ArrayList(10);
59     static protected XSimpleFileAccess m_xSFA;
60     protected XComponentContext m_xCtx;
61     private ParcelContainer parent = null;
62     private Collection childContainers = new ArrayList(10);;
63     private boolean isPkgContainer = false;
64 
65     /**
66      * Tests if this <tt>ParcelContainer</tt> represents an UNO package
67      * or sub package within an UNO package
68      *
69      * @return    <tt>true</tt> if has parent <tt>false</tt> otherwise
70      */
isUnoPkg()71     public boolean isUnoPkg() { return isPkgContainer; }
72     /**
73      * Tests if this <tt>ParcelContainer</tt> has a parent
74      * a parent.
75      *
76      * @return    <tt>true</tt> if has parent <tt>false</tt> otherwise
77      */
hasParent()78     public boolean hasParent()
79     {
80         if ( parent == null )
81         {
82             return false;
83         }
84         return true;
85     }
86 
87     /**
88      * Returns this <tt>ParcelContainer</tt>'s  parent
89      *
90      * @return    <tt>ParcelContainer</tt> if has parent null otherwise
91      */
parent()92     public ParcelContainer parent()
93     {
94         return parent;
95     }
96 
97     /**
98      * Returns all child <tt>ParcelContainer</tt>
99      * this instance of <tt>ParcelContainer</tt>
100      *
101      * @return    a new array of ParcelContainers. A zero
102      * length array is returned if no child ParcelContainers.
103      */
getChildContainers()104     public ParcelContainer[] getChildContainers()
105     {
106         if ( childContainers.isEmpty() )
107         {
108             return new ParcelContainer[0];
109         }
110         return (ParcelContainer[]) childContainers.toArray( new ParcelContainer[0] );
111 
112     }
113     /**
114      * Removes a child <tt>ParcelContainer</tt>
115      * from this instance.
116      * @param   child  <tt>ParcelContainer</tt> to be added.
117      *
118      * @return    <tt>true</tt> if child successfully removed
119      */
removeChildContainer( ParcelContainer child )120     public boolean removeChildContainer( ParcelContainer child )
121     {
122         return childContainers.remove( child );
123     }
124 
125     /**
126      * Adds a new child <tt>ParcelContainer</tt>
127      * to this instance.
128      * @param   child  <tt>ParcelContainer</tt> to be added.
129      *
130      */
addChildContainer( ParcelContainer child )131     public void addChildContainer( ParcelContainer child )
132     {
133         childContainers.add( child );
134     }
135 
136     /**
137      * Returns a child <tt>ParcelContainer</tt> whose location
138      * matches the <tt>location</tt> argument passed to this method.
139      * @param    key the <tt>location</tt> which is to
140      *           be matched.
141      *
142      * @return    child <tt>ParcelContainer</tt> or <null> if none
143      * found.
144      */
145 
getChildContainer( String key )146     public ParcelContainer getChildContainer( String key )
147     {
148         ParcelContainer result = null;
149         Iterator iter = childContainers.iterator();
150         while ( iter.hasNext() )
151         {
152             ParcelContainer c = (ParcelContainer) iter.next();
153             String location = ScriptMetaData.getLocationPlaceHolder(
154                 c.containerUrl, c.getName());
155 
156             if ( key.equals( location ) )
157             {
158                 result = c;
159                 break;
160             }
161         }
162         return result;
163     }
164 
165     /**
166      * Returns a child <tt>ParcelContainer</tt> whose member
167      * <tt>containerUrl</tt> matches the <tt>containerUrl</tt>
168      * argument passed to this method.
169      * @param    containerUrl the <tt>containerUrl</tt> which is to
170      *           be matched.
171      *
172      * @return    child <tt>ParcelContainer</tt> or <null> if none
173      * found.
174      */
175 
getChildContainerForURL( String containerUrl )176     public ParcelContainer getChildContainerForURL( String containerUrl )
177     {
178         ParcelContainer result = null;
179         Iterator iter = childContainers.iterator();
180         while ( iter.hasNext() )
181         {
182             ParcelContainer c = (ParcelContainer) iter.next();
183             if ( containerUrl.equals( c.containerUrl ) )
184             {
185                 result = c;
186                 break;
187             }
188         }
189         return result;
190     }
191 
192     /**
193      * Returns Name of this container. Name of this <tt>ParcelContainer</tt>
194      * is determined from the <tt>containerUrl</tt> as the last portion
195      * of the URL after the last forward slash.
196      * @return    name of <tt>ParcelContainer</tt>
197      * found.
198      */
getName()199     public String getName()
200     {
201         String name = null;
202         // TODO handler package ParcelContainer?
203         if (  !containerUrl.startsWith( "vnd.sun.star.tdoc:" ) )
204         {
205             // return name
206             String decodedUrl = java.net.URLDecoder.decode( containerUrl );
207             int indexOfSlash = decodedUrl.lastIndexOf( "/" );
208             if ( indexOfSlash != -1 )
209             {
210                 name =  decodedUrl.substring( indexOfSlash + 1 );
211             }
212         }
213         else
214         {
215             name =  "document";
216         }
217         return name;
218     }
219 
220     /**
221      * Initializes a newly created <code>ParcelContainer</code> object.
222      * @param    xCtx UNO component context
223      * @param   containerUrl location of this container.
224      * @param   language language for which entries are stored
225      * @return    name of <tt>ParcelContainer</tt>
226      * @throws    IllegalArgumentException
227      * @throws    WrappedTargetException
228      */
229 
ParcelContainer( XComponentContext xCtx, String containerUrl, String language )230     public ParcelContainer( XComponentContext xCtx, String containerUrl, String language ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
231 
232     {
233         this( null, xCtx, containerUrl, language, true );
234     }
235 
236     /**
237      * Initializes a newly created <code>ParcelContainer</code> object.
238      * @param    xCtx UNO component context
239      * @param   containerUrl location of this container.
240      * @param   language language for which entries are stored
241      * @param   loadParcels set to <tt>true</tt> if parcels are to be loaded
242      *          on construction.
243      * @throws    com.sun.star.lang.IllegalArgumentException
244      * @throws    WrappedTargetException
245      */
ParcelContainer( XComponentContext xCtx, String containerUrl, String language, boolean loadParcels )246     public ParcelContainer( XComponentContext xCtx, String containerUrl, String language, boolean loadParcels ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
247     {
248         this( null, xCtx, containerUrl, language, loadParcels );
249     }
250 
251     /**
252      * Initializes a newly created <code>ParcelContainer</code> object.
253      * @param   parent parent ParcelContainer
254      * @param    xCtx UNO component context
255      * @param   containerUrl location of this container.
256      * @param   language language for which entries are stored
257      * @param   loadParcels set to <tt>true</tt> if parcels are to be loaded
258      *          on construction.
259      * @return    name of <tt>ParcelContainer</tt>
260      * @throws    IllegalArgumentException
261      */
262 
ParcelContainer( ParcelContainer parent, XComponentContext xCtx, String containerUrl, String language, boolean loadParcels )263     public ParcelContainer( ParcelContainer parent, XComponentContext xCtx, String containerUrl, String language, boolean loadParcels ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
264 
265     {
266         LogUtils.DEBUG("Creating ParcelContainer for " + containerUrl + " loadParcels = " + loadParcels + " language = " + language );
267         this.m_xCtx = xCtx;
268         this.language = language;
269         this.parent = parent;
270         this.containerUrl = containerUrl;
271 
272         initSimpleFileAccess();
273         boolean parentIsPkgContainer = false;
274 
275         if ( parent != null )
276         {
277             parentIsPkgContainer = parent.isUnoPkg();
278         }
279 
280         if ( containerUrl.endsWith("uno_packages") || parentIsPkgContainer  )
281         {
282             isPkgContainer = true;
283         }
284 
285         if ( loadParcels )
286         {
287             loadParcels();
288         }
289     }
290 
291 
getContainerURL()292     public String getContainerURL() { return this.containerUrl; }
293 
initSimpleFileAccess()294     private synchronized void initSimpleFileAccess()
295     {
296         if ( m_xSFA != null )
297         {
298             return;
299         }
300         try
301         {
302             m_xSFA = ( XSimpleFileAccess )UnoRuntime.queryInterface(
303                 XSimpleFileAccess.class,
304                 m_xCtx.getServiceManager().createInstanceWithContext(
305                     "com.sun.star.ucb.SimpleFileAccess", m_xCtx ) );
306         }
307         catch ( Exception e )
308         {
309             // TODO should throw
310             LogUtils.DEBUG("Error instantiating simplefile access ");
311             LogUtils.DEBUG( LogUtils.getTrace( e ) );
312         }
313     }
314 
getParcelContainerDir()315     public String getParcelContainerDir()
316     {
317         // If this container does not represent an uno-package
318         // then then it is a document, user or share
319         // in each case the convention is to have a Scripts/[language]
320         // dir where scripts reside
321         if (  !isUnoPkg() )
322         {
323             return PathUtils.make_url( containerUrl  ,  "Scripts/" + language.toLowerCase() );
324         }
325         return containerUrl;
326     }
getByName( String aName )327     public Object getByName( String aName ) throws com.sun.star.container.NoSuchElementException, WrappedTargetException
328     {
329         Parcel parcel = null;
330         try
331         {
332             if ( hasElements() )
333             {
334                 Iterator iter = parcels.iterator();
335                 while ( iter.hasNext() )
336                 {
337                     Parcel parcelToCheck = (Parcel)iter.next();
338 
339                     if ( parcelToCheck.getName().equals( aName ) )
340                     {
341                        parcel = parcelToCheck;
342                        break;
343                     }
344                 }
345             }
346         }
347         catch ( Exception e)
348         {
349             throw new WrappedTargetException( e.toString() );
350         }
351         if ( parcel == null )
352         {
353             throw new com.sun.star.container.NoSuchElementException( "Macro Library " + aName + " not found" );
354         }
355         return parcel;
356     }
getElementNames()357     public String[] getElementNames()
358     {
359         if ( hasElements() )
360         {
361             Parcel[] theParcels = (Parcel[])parcels.toArray( new Parcel[0] );
362             String[] names = new String[ theParcels.length ];
363             for ( int count = 0; count < names.length; count++ )
364             {
365                 names[count] = theParcels[ count ].getName();
366             }
367             return names;
368         }
369 
370         return new String[0];
371     }
hasByName( String aName )372     public boolean hasByName( String aName )
373     {
374         boolean isFound = false;
375         try
376         {
377             if ( getByName( aName ) != null )
378             {
379                 isFound = true;
380             }
381 
382         }
383         catch ( Exception e )
384         {
385             //TODO - handle trace
386         }
387         return isFound;
388     }
getElementType()389     public Type getElementType()
390     {
391         return new Type();
392     }
hasElements()393     public boolean hasElements()
394     {
395         if ( parcels == null || parcels.isEmpty() )
396         {
397             return false;
398         }
399         return true;
400     }
401 
loadParcels()402     private void loadParcels() throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
403     {
404         try
405         {
406             LogUtils.DEBUG("About to load parcels from " + containerUrl );
407             if ( m_xSFA.isFolder( getParcelContainerDir() ) )
408             {
409                 LogUtils.DEBUG( getParcelContainerDir() + " is a folder " );
410                 String[] children = m_xSFA.getFolderContents( getParcelContainerDir(), true );
411                 parcels  = new ArrayList(children.length);
412                 for ( int  i = 0; i < children.length; i++)
413                 {
414                     LogUtils.DEBUG("Processing " + children[ i ] );
415                     try
416                     {
417                         loadParcel( children[ i ] );
418                     }
419                     catch (java.lang.Exception e)
420                     {
421                         // print an error message and move on to
422                         // the next parcel
423                         LogUtils.DEBUG("ParcelContainer.loadParcels caught " + e.getClass().getName() + " exception loading parcel " + children[i] + ": " + e.getMessage() );
424                     }
425                 }
426             }
427             else
428             {
429                 LogUtils.DEBUG(" ParcelCOntainer.loadParcels " + getParcelContainerDir()  + " is not a folder ");
430             }
431 
432         }
433         catch ( com.sun.star.ucb.CommandAbortedException e )
434         {
435             LogUtils.DEBUG("ParcelContainer.loadParcels caught exception processing folders for " + getParcelContainerDir()  );
436             LogUtils.DEBUG("TRACE: " + LogUtils.getTrace(e) );
437             throw new com.sun.star.lang.WrappedTargetException( e.toString() );
438         }
439         catch ( com.sun.star.uno.Exception e )
440         {
441             LogUtils.DEBUG("ParcelContainer.loadParcels caught exception processing folders for " + getParcelContainerDir()  );
442             LogUtils.DEBUG("TRACE: " + LogUtils.getTrace(e) );
443             throw new com.sun.star.lang.WrappedTargetException( e.toString() );
444         }
445     }
446 
createParcel(String name)447     public  XNameContainer createParcel(String name) throws ElementExistException, com.sun.star.lang.WrappedTargetException
448     {
449         Parcel p = null;
450         if ( hasByName( name ) )
451         {
452              throw new ElementExistException( "Parcel " + name + " already exists" );
453         }
454         String pathToParcel =  PathUtils.make_url( getParcelContainerDir() ,  name );
455 
456         try
457         {
458             LogUtils.DEBUG("ParcelContainer.createParcel, creating folder " + pathToParcel );
459             m_xSFA.createFolder( pathToParcel );
460 
461             LogUtils.DEBUG("ParcelContainer.createParcel, folder " + pathToParcel  + " created ");
462 
463             ParcelDescriptor pd = new ParcelDescriptor();
464             pd.setLanguage( language );
465             String parcelDesc = PathUtils.make_url( pathToParcel, ParcelDescriptor.PARCEL_DESCRIPTOR_NAME );
466             XSimpleFileAccess2 xSFA2 = ( XSimpleFileAccess2 )
467                 UnoRuntime.queryInterface( XSimpleFileAccess2.class, m_xSFA );
468             if ( xSFA2 != null )
469             {
470                 LogUtils.DEBUG("createParcel() Using XSIMPLEFILEACCESS2 " + parcelDesc );
471                 ByteArrayOutputStream bos = new ByteArrayOutputStream( 1024 );
472                 pd.write( bos );
473                 bos.close();
474                 ByteArrayInputStream bis = new ByteArrayInputStream( bos.toByteArray() );
475                 XInputStreamImpl xis = new XInputStreamImpl( bis );
476                 xSFA2.writeFile( parcelDesc, xis );
477                 xis.closeInput();
478                 p = loadParcel( pathToParcel );
479             }
480         }
481         catch ( Exception e )
482         {
483 
484             LogUtils.DEBUG("createParcel() Exception while attempting to create = " + name );
485             throw  new com.sun.star.lang.WrappedTargetException( e.toString() );
486         }
487         return p;
488     }
489 
loadParcel( String parcelUrl )490     public Parcel loadParcel( String parcelUrl ) throws com.sun.star.lang.WrappedTargetException, com.sun.star.lang.IllegalArgumentException
491     {
492 
493         String name = null;
494 
495         String parcelDescUrl =  PathUtils.make_url( parcelUrl,  ParcelDescriptor.PARCEL_DESCRIPTOR_NAME );
496         Parcel parcel = null;
497 
498         XInputStream xis = null;
499         InputStream is = null;
500 
501         try
502         {
503             if ( m_xSFA.exists( parcelDescUrl ) )
504             {
505                 LogUtils.DEBUG("ParcelContainer.loadParcel opening " + parcelDescUrl );
506                 xis = m_xSFA.openFileRead( parcelDescUrl );
507                 is = new XInputStreamWrapper( xis );
508 
509                 ParcelDescriptor pd = new ParcelDescriptor(is) ;
510                 try
511                 {
512                     is.close();
513                     is = null;
514                 }
515                 catch ( Exception e )
516                 {
517                     LogUtils.DEBUG("ParcelContainer.loadParcel Exception when closing stream for  " + parcelDescUrl + " :" + e );
518                 }
519                 LogUtils.DEBUG("ParcelContainer.loadParcel closed " + parcelDescUrl );
520                 if ( !pd.getLanguage().equals( language ) )
521                 {
522                     LogUtils.DEBUG("ParcelContainer.loadParcel Language of Parcel does not match this container ");
523                     return null;
524                 }
525                 LogUtils.DEBUG("Processing " + parcelDescUrl + " closed " );
526 
527                 int indexOfSlash = parcelUrl.lastIndexOf("/");
528                 name = parcelUrl.substring( indexOfSlash + 1 );
529 
530                 parcel = new Parcel( m_xSFA, this, pd, name );
531 
532                 LogUtils.DEBUG(" ParcelContainer.loadParcel created parcel for " + parcelDescUrl + " for language " + language );
533                 parcels.add( parcel );
534             }
535             else
536             {
537                 throw new java.io.IOException( parcelDescUrl + " does NOT exist!");
538             }
539         }
540         catch ( com.sun.star.ucb.CommandAbortedException e )
541         {
542 
543             LogUtils.DEBUG("loadParcel() Exception while accessing filesystem url = " + parcelDescUrl + e );
544             throw  new com.sun.star.lang.WrappedTargetException( e.toString() );
545         }
546         catch ( java.io.IOException e )
547         {
548             LogUtils.DEBUG("ParcelContainer.loadParcel() caught IOException while accessing " + parcelDescUrl + ": " + e );
549             throw  new com.sun.star.lang.WrappedTargetException( e.toString() );
550         }
551         catch (  com.sun.star.uno.Exception e )
552         {
553 
554             LogUtils.DEBUG("loadParcel() Exception while accessing filesystem url = " + parcelDescUrl + e );
555             throw  new com.sun.star.lang.WrappedTargetException( e.toString() );
556         }
557 
558         finally
559         {
560             if ( is != null )
561             {
562                 try
563                 {
564                     is.close(); // is will close xis
565                 }
566                 catch ( Exception ignore )
567                 {
568                 }
569             }
570             else if ( xis != null )
571             {
572                 try
573                 {
574                     xis.closeInput();
575                 }
576                 catch ( Exception ignore )
577                 {
578                 }
579             }
580         }
581         return parcel;
582     }
renameParcel(String oldName, String newName)583     public void renameParcel(String oldName, String newName) throws com.sun.star.container.NoSuchElementException, com.sun.star.lang.WrappedTargetException
584     {
585         LogUtils.DEBUG(" ** ParcelContainer Renaming parcel " + oldName + " to " + newName );
586         LogUtils.DEBUG(" ** ParcelContainer is " + this );
587         Parcel p = (Parcel)getByName( oldName );
588         if ( p == null )
589         {
590             throw new com.sun.star.container.NoSuchElementException( "No parcel named " + oldName );
591         }
592         String oldParcelDirUrl = PathUtils.make_url( getParcelContainerDir(),
593             oldName );
594         String newParcelDirUrl = PathUtils.make_url( getParcelContainerDir(),
595             newName );
596         try
597         {
598             if (!m_xSFA.isFolder( oldParcelDirUrl ) )
599             {
600                 Exception e = new com.sun.star.io.IOException("Invalid Parcel directory: " + oldName );
601                 throw new com.sun.star.lang.WrappedTargetException( e.toString() );
602             }
603             LogUtils.DEBUG(" ** ParcelContainer Renaming folder " + oldParcelDirUrl + " to " + newParcelDirUrl );
604             m_xSFA.move( oldParcelDirUrl, newParcelDirUrl );
605         }
606         catch ( com.sun.star.ucb.CommandAbortedException ce )
607         {
608             LogUtils.DEBUG(" ** ParcelContainer Renaming failed with " + ce  );
609             throw new com.sun.star.lang.WrappedTargetException( ce.toString() );
610         }
611         catch ( com.sun.star.uno.Exception e )
612         {
613             LogUtils.DEBUG(" ** ParcelContainer Renaming failed with " + e  );
614             throw new com.sun.star.lang.WrappedTargetException( e.toString() );
615         }
616 
617         p.rename( newName );
618     }
619     // removes but doesn't physically delele parcel from container
removeParcel(String name)620     public boolean removeParcel(String name) throws com.sun.star.container.NoSuchElementException, com.sun.star.lang.WrappedTargetException
621     {
622         boolean result = false;
623         Parcel p = (Parcel)getByName( name );
624         if ( p == null )
625         {
626             throw new com.sun.star.container.NoSuchElementException("No parcel named " + name );
627         }
628 
629         result =  parcels.remove( p );
630         return result;
631     }
deleteParcel(String name)632     public boolean deleteParcel(String name) throws com.sun.star.container.NoSuchElementException, com.sun.star.lang.WrappedTargetException
633     {
634         LogUtils.DEBUG( "deleteParcel for containerURL " + containerUrl + " name = " + name  + " Langueg = " + language );
635         boolean result = false;
636 
637         Parcel p = (Parcel)getByName( name );
638         if ( p == null )
639         {
640             throw new com.sun.star.container.NoSuchElementException("No parcel named " + name );
641         }
642 
643         try
644         {
645             String pathToParcel =  PathUtils.make_url( getParcelContainerDir(),   name );
646             m_xSFA.kill( pathToParcel );
647         }
648         catch( Exception e )
649         {
650             LogUtils.DEBUG("Error deleteing parcel " + name );
651             throw new com.sun.star.lang.WrappedTargetException( e.toString() );
652         }
653 
654         result =  parcels.remove( p );
655         return result;
656     }
657 
getLanguage()658     public String getLanguage() { return language; }
659 
findScript( ParsedScriptUri parsedUri )660     public ScriptMetaData findScript( ParsedScriptUri  parsedUri ) throws  com.sun.star.container.NoSuchElementException,  com.sun.star.lang.WrappedTargetException
661     {
662         ScriptMetaData scriptData = null;
663         Parcel p = null;
664         p = (Parcel)getByName( parsedUri.parcel);
665         scriptData = (ScriptMetaData)p.getByName( parsedUri.function);
666         LogUtils.DEBUG("** found script data for " +  parsedUri.function + " script is " + scriptData );
667         return scriptData;
668 
669     }
parseScriptUri( String scriptURI )670 public  ParsedScriptUri parseScriptUri( String scriptURI ) throws com.sun.star.lang.IllegalArgumentException
671 {
672 
673         XMultiComponentFactory xMcFac = null;
674         XUriReferenceFactory xFac = null;
675 
676         try
677         {
678             xMcFac = m_xCtx.getServiceManager();
679             xFac = ( XUriReferenceFactory )
680                 UnoRuntime.queryInterface( XUriReferenceFactory.class,
681                     xMcFac.createInstanceWithContext(
682                         "com.sun.star.uri.UriReferenceFactory", m_xCtx ) );
683         }
684         catch( com.sun.star.uno.Exception e )
685         {
686             LogUtils.DEBUG("Problems parsing  URL:" + e.toString() );
687             throw new  com.sun.star.lang.IllegalArgumentException( "Problems parsing  URL reason: " + e.toString() );
688         }
689         if ( xFac == null )
690         {
691             LogUtils.DEBUG("Failed to create UrlReference factory");
692             throw new  com.sun.star.lang.IllegalArgumentException( "Failed to create UrlReference factory for url " + scriptURI );
693         }
694 
695         XUriReference uriRef = xFac.parse( scriptURI );
696         XVndSunStarScriptUrl  sfUri = ( XVndSunStarScriptUrl )
697             UnoRuntime.queryInterface( XVndSunStarScriptUrl.class, uriRef );
698 
699         if ( sfUri == null )
700         {
701             LogUtils.DEBUG("Failed to parse url");
702             throw new  com.sun.star.lang.IllegalArgumentException( "Failed to parse url " + scriptURI );
703         }
704 
705         ParsedScriptUri parsedUri = new ParsedScriptUri();
706         // parse language
707         parsedUri.language = sfUri.getParameter("language");
708         parsedUri.function= sfUri.getName();
709         parsedUri.parcel = "";
710 
711         // parse parcel name;
712         StringTokenizer tokenizer = new StringTokenizer( parsedUri.function, "." );
713 
714         if ( tokenizer.hasMoreElements() )
715         {
716             parsedUri.parcel = (String)tokenizer.nextElement();
717             LogUtils.DEBUG("** parcelName = " + parsedUri.parcel );
718         }
719 
720         if ( parsedUri.function != null && ( parsedUri.function.length() > 0 ) )
721         {
722             // strip out parcel name
723             parsedUri.function = parsedUri.function.substring( parsedUri.parcel.length() + 1);
724         }
725 
726         // parse location
727         parsedUri.location = sfUri.getParameter("location");
728 
729         // TODO basic sanity check on language, location, functioname, parcel
730         // should be correct e.g. verified  by MSP and LangProvider by the
731         // time its got to here
732 
733         LogUtils.DEBUG("** location = " + parsedUri.location +
734             "\nfunction = " + parsedUri.function +
735             "\nparcel = " + parsedUri.parcel +
736             "\nlocation = " + parsedUri.location );
737         return parsedUri;
738 }
739 
740 
741 }
742