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      */
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      */
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      */
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      */
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      */
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      */
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 
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 
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      */
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 
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      * @return    name of <tt>ParcelContainer</tt>
244      * @throws    IllegalArgumentException
245      * @throws    WrappedTargetException
246      */
247     public ParcelContainer( XComponentContext xCtx, String containerUrl, String language, boolean loadParcels ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
248     {
249         this( null, xCtx, containerUrl, language, loadParcels );
250     }
251 
252     /**
253      * Initializes a newly created <code>ParcelContainer</code> object.
254      * @param   parent parent ParcelContainer
255      * @param    xCtx UNO component context
256      * @param   containerUrl location of this container.
257      * @param   language language for which entries are stored
258      * @param   loadParcels set to <tt>true</tt> if parcels are to be loaded
259      *          on construction.
260      * @return    name of <tt>ParcelContainer</tt>
261      * @throws    IllegalArgumentException
262      */
263 
264     public ParcelContainer( ParcelContainer parent, XComponentContext xCtx, String containerUrl, String language, boolean loadParcels ) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
265 
266     {
267         LogUtils.DEBUG("Creating ParcelContainer for " + containerUrl + " loadParcels = " + loadParcels + " language = " + language );
268         this.m_xCtx = xCtx;
269         this.language = language;
270         this.parent = parent;
271         this.containerUrl = containerUrl;
272 
273         initSimpleFileAccess();
274         boolean parentIsPkgContainer = false;
275 
276         if ( parent != null )
277         {
278             parentIsPkgContainer = parent.isUnoPkg();
279         }
280 
281         if ( containerUrl.endsWith("uno_packages") || parentIsPkgContainer  )
282         {
283             isPkgContainer = true;
284         }
285 
286         if ( loadParcels )
287         {
288             loadParcels();
289         }
290     }
291 
292 
293     public String getContainerURL() { return this.containerUrl; }
294 
295     private synchronized void initSimpleFileAccess()
296     {
297         if ( m_xSFA != null )
298         {
299             return;
300         }
301         try
302         {
303             m_xSFA = ( XSimpleFileAccess )UnoRuntime.queryInterface(
304                 XSimpleFileAccess.class,
305                 m_xCtx.getServiceManager().createInstanceWithContext(
306                     "com.sun.star.ucb.SimpleFileAccess", m_xCtx ) );
307         }
308         catch ( Exception e )
309         {
310             // TODO should throw
311             LogUtils.DEBUG("Error instantiating simplefile access ");
312             LogUtils.DEBUG( LogUtils.getTrace( e ) );
313         }
314     }
315 
316     public String getParcelContainerDir()
317     {
318         // If this container does not represent an uno-package
319         // then then it is a document, user or share
320         // in each case the convention is to have a Scripts/[language]
321         // dir where scripts reside
322         if (  !isUnoPkg() )
323         {
324             return PathUtils.make_url( containerUrl  ,  "Scripts/" + language.toLowerCase() );
325         }
326         return containerUrl;
327     }
328     public Object getByName( String aName ) throws com.sun.star.container.NoSuchElementException, WrappedTargetException
329     {
330         Parcel parcel = null;
331         try
332         {
333             if ( hasElements() )
334             {
335                 Iterator iter = parcels.iterator();
336                 while ( iter.hasNext() )
337                 {
338                     Parcel parcelToCheck = (Parcel)iter.next();
339 
340                     if ( parcelToCheck.getName().equals( aName ) )
341                     {
342                        parcel = parcelToCheck;
343                        break;
344                     }
345                 }
346             }
347         }
348         catch ( Exception e)
349         {
350             throw new WrappedTargetException( e.toString() );
351         }
352         if ( parcel == null )
353         {
354             throw new com.sun.star.container.NoSuchElementException( "Macro Library " + aName + " not found" );
355         }
356         return parcel;
357     }
358     public String[] getElementNames()
359     {
360         if ( hasElements() )
361         {
362             Parcel[] theParcels = (Parcel[])parcels.toArray( new Parcel[0] );
363             String[] names = new String[ theParcels.length ];
364             for ( int count = 0; count < names.length; count++ )
365             {
366                 names[count] = theParcels[ count ].getName();
367             }
368             return names;
369         }
370 
371         return new String[0];
372     }
373     public boolean hasByName( String aName )
374     {
375         boolean isFound = false;
376         try
377         {
378             if ( getByName( aName ) != null )
379             {
380                 isFound = true;
381             }
382 
383         }
384         catch ( Exception e )
385         {
386             //TODO - handle trace
387         }
388         return isFound;
389     }
390     public Type getElementType()
391     {
392         return new Type();
393     }
394     public boolean hasElements()
395     {
396         if ( parcels == null || parcels.isEmpty() )
397         {
398             return false;
399         }
400         return true;
401     }
402 
403     private void loadParcels() throws com.sun.star.lang.IllegalArgumentException, com.sun.star.lang.WrappedTargetException
404     {
405         try
406         {
407             LogUtils.DEBUG("About to load parcels from " + containerUrl );
408             if ( m_xSFA.isFolder( getParcelContainerDir() ) )
409             {
410                 LogUtils.DEBUG( getParcelContainerDir() + " is a folder " );
411                 String[] children = m_xSFA.getFolderContents( getParcelContainerDir(), true );
412                 parcels  = new ArrayList(children.length);
413                 for ( int  i = 0; i < children.length; i++)
414                 {
415                     LogUtils.DEBUG("Processing " + children[ i ] );
416                     try
417                     {
418                         loadParcel( children[ i ] );
419                     }
420                     catch (java.lang.Exception e)
421                     {
422                         // print an error message and move on to
423                         // the next parcel
424                         LogUtils.DEBUG("ParcelContainer.loadParcels caught " + e.getClass().getName() + " exception loading parcel " + children[i] + ": " + e.getMessage() );
425                     }
426                 }
427             }
428             else
429             {
430                 LogUtils.DEBUG(" ParcelCOntainer.loadParcels " + getParcelContainerDir()  + " is not a folder ");
431             }
432 
433         }
434         catch ( com.sun.star.ucb.CommandAbortedException e )
435         {
436             LogUtils.DEBUG("ParcelContainer.loadParcels caught exception processing folders for " + getParcelContainerDir()  );
437             LogUtils.DEBUG("TRACE: " + LogUtils.getTrace(e) );
438             throw new com.sun.star.lang.WrappedTargetException( e.toString() );
439         }
440         catch ( com.sun.star.uno.Exception e )
441         {
442             LogUtils.DEBUG("ParcelContainer.loadParcels caught exception processing folders for " + getParcelContainerDir()  );
443             LogUtils.DEBUG("TRACE: " + LogUtils.getTrace(e) );
444             throw new com.sun.star.lang.WrappedTargetException( e.toString() );
445         }
446     }
447 
448     public  XNameContainer createParcel(String name) throws ElementExistException, com.sun.star.lang.WrappedTargetException
449     {
450         Parcel p = null;
451         if ( hasByName( name ) )
452         {
453              throw new ElementExistException( "Parcel " + name + " already exists" );
454         }
455         String pathToParcel =  PathUtils.make_url( getParcelContainerDir() ,  name );
456 
457         try
458         {
459             LogUtils.DEBUG("ParcelContainer.createParcel, creating folder " + pathToParcel );
460             m_xSFA.createFolder( pathToParcel );
461 
462             LogUtils.DEBUG("ParcelContainer.createParcel, folder " + pathToParcel  + " created ");
463 
464             ParcelDescriptor pd = new ParcelDescriptor();
465             pd.setLanguage( language );
466             String parcelDesc = PathUtils.make_url( pathToParcel, ParcelDescriptor.PARCEL_DESCRIPTOR_NAME );
467             XSimpleFileAccess2 xSFA2 = ( XSimpleFileAccess2 )
468                 UnoRuntime.queryInterface( XSimpleFileAccess2.class, m_xSFA );
469             if ( xSFA2 != null )
470             {
471                 LogUtils.DEBUG("createParcel() Using XSIMPLEFILEACCESS2 " + parcelDesc );
472                 ByteArrayOutputStream bos = new ByteArrayOutputStream( 1024 );
473                 pd.write( bos );
474                 bos.close();
475                 ByteArrayInputStream bis = new ByteArrayInputStream( bos.toByteArray() );
476                 XInputStreamImpl xis = new XInputStreamImpl( bis );
477                 xSFA2.writeFile( parcelDesc, xis );
478                 xis.closeInput();
479                 p = loadParcel( pathToParcel );
480             }
481         }
482         catch ( Exception e )
483         {
484 
485             LogUtils.DEBUG("createParcel() Exception while attempting to create = " + name );
486             throw  new com.sun.star.lang.WrappedTargetException( e.toString() );
487         }
488         return p;
489     }
490 
491     public Parcel loadParcel( String parcelUrl ) throws com.sun.star.lang.WrappedTargetException, com.sun.star.lang.IllegalArgumentException
492     {
493 
494         String name = null;
495 
496         String parcelDescUrl =  PathUtils.make_url( parcelUrl,  ParcelDescriptor.PARCEL_DESCRIPTOR_NAME );
497         Parcel parcel = null;
498 
499         XInputStream xis = null;
500         InputStream is = null;
501 
502         try
503         {
504             if ( m_xSFA.exists( parcelDescUrl ) )
505             {
506                 LogUtils.DEBUG("ParcelContainer.loadParcel opening " + parcelDescUrl );
507                 xis = m_xSFA.openFileRead( parcelDescUrl );
508                 is = new XInputStreamWrapper( xis );
509 
510                 ParcelDescriptor pd = new ParcelDescriptor(is) ;
511                 try
512                 {
513                     is.close();
514                     is = null;
515                 }
516                 catch ( Exception e )
517                 {
518                     LogUtils.DEBUG("ParcelContainer.loadParcel Exception when closing stream for  " + parcelDescUrl + " :" + e );
519                 }
520                 LogUtils.DEBUG("ParcelContainer.loadParcel closed " + parcelDescUrl );
521                 if ( !pd.getLanguage().equals( language ) )
522                 {
523                     LogUtils.DEBUG("ParcelContainer.loadParcel Language of Parcel does not match this container ");
524                     return null;
525                 }
526                 LogUtils.DEBUG("Processing " + parcelDescUrl + " closed " );
527 
528                 int indexOfSlash = parcelUrl.lastIndexOf("/");
529                 name = parcelUrl.substring( indexOfSlash + 1 );
530 
531                 parcel = new Parcel( m_xSFA, this, pd, name );
532 
533                 LogUtils.DEBUG(" ParcelContainer.loadParcel created parcel for " + parcelDescUrl + " for language " + language );
534                 parcels.add( parcel );
535             }
536             else
537             {
538                 throw new java.io.IOException( parcelDescUrl + " does NOT exist!");
539             }
540         }
541         catch ( com.sun.star.ucb.CommandAbortedException e )
542         {
543 
544             LogUtils.DEBUG("loadParcel() Exception while accessing filesystem url = " + parcelDescUrl + e );
545             throw  new com.sun.star.lang.WrappedTargetException( e.toString() );
546         }
547         catch ( java.io.IOException e )
548         {
549             LogUtils.DEBUG("ParcelContainer.loadParcel() caught IOException while accessing " + parcelDescUrl + ": " + e );
550             throw  new com.sun.star.lang.WrappedTargetException( e.toString() );
551         }
552         catch (  com.sun.star.uno.Exception e )
553         {
554 
555             LogUtils.DEBUG("loadParcel() Exception while accessing filesystem url = " + parcelDescUrl + e );
556             throw  new com.sun.star.lang.WrappedTargetException( e.toString() );
557         }
558 
559         finally
560         {
561             if ( is != null )
562             {
563                 try
564                 {
565                     is.close(); // is will close xis
566                 }
567                 catch ( Exception ignore )
568                 {
569                 }
570             }
571             else if ( xis != null )
572             {
573                 try
574                 {
575                     xis.closeInput();
576                 }
577                 catch ( Exception ignore )
578                 {
579                 }
580             }
581         }
582         return parcel;
583     }
584     public void renameParcel(String oldName, String newName) throws com.sun.star.container.NoSuchElementException, com.sun.star.lang.WrappedTargetException
585     {
586         LogUtils.DEBUG(" ** ParcelContainer Renaming parcel " + oldName + " to " + newName );
587         LogUtils.DEBUG(" ** ParcelContainer is " + this );
588         Parcel p = (Parcel)getByName( oldName );
589         if ( p == null )
590         {
591             throw new com.sun.star.container.NoSuchElementException( "No parcel named " + oldName );
592         }
593         String oldParcelDirUrl = PathUtils.make_url( getParcelContainerDir(),
594             oldName );
595         String newParcelDirUrl = PathUtils.make_url( getParcelContainerDir(),
596             newName );
597         try
598         {
599             if (!m_xSFA.isFolder( oldParcelDirUrl ) )
600             {
601                 Exception e = new com.sun.star.io.IOException("Invalid Parcel directory: " + oldName );
602                 throw new com.sun.star.lang.WrappedTargetException( e.toString() );
603             }
604             LogUtils.DEBUG(" ** ParcelContainer Renaming folder " + oldParcelDirUrl + " to " + newParcelDirUrl );
605             m_xSFA.move( oldParcelDirUrl, newParcelDirUrl );
606         }
607         catch ( com.sun.star.ucb.CommandAbortedException ce )
608         {
609             LogUtils.DEBUG(" ** ParcelContainer Renaming failed with " + ce  );
610             throw new com.sun.star.lang.WrappedTargetException( ce.toString() );
611         }
612         catch ( com.sun.star.uno.Exception e )
613         {
614             LogUtils.DEBUG(" ** ParcelContainer Renaming failed with " + e  );
615             throw new com.sun.star.lang.WrappedTargetException( e.toString() );
616         }
617 
618         p.rename( newName );
619     }
620     // removes but doesn't physically delele parcel from container
621     public boolean removeParcel(String name) throws com.sun.star.container.NoSuchElementException, com.sun.star.lang.WrappedTargetException
622     {
623         boolean result = false;
624         Parcel p = (Parcel)getByName( name );
625         if ( p == null )
626         {
627             throw new com.sun.star.container.NoSuchElementException("No parcel named " + name );
628         }
629 
630         result =  parcels.remove( p );
631         return result;
632     }
633     public boolean deleteParcel(String name) throws com.sun.star.container.NoSuchElementException, com.sun.star.lang.WrappedTargetException
634     {
635         LogUtils.DEBUG( "deleteParcel for containerURL " + containerUrl + " name = " + name  + " Langueg = " + language );
636         boolean result = false;
637 
638         Parcel p = (Parcel)getByName( name );
639         if ( p == null )
640         {
641             throw new com.sun.star.container.NoSuchElementException("No parcel named " + name );
642         }
643 
644         try
645         {
646             String pathToParcel =  PathUtils.make_url( getParcelContainerDir(),   name );
647             m_xSFA.kill( pathToParcel );
648         }
649         catch( Exception e )
650         {
651             LogUtils.DEBUG("Error deleteing parcel " + name );
652             throw new com.sun.star.lang.WrappedTargetException( e.toString() );
653         }
654 
655         result =  parcels.remove( p );
656         return result;
657     }
658 
659     public String getLanguage() { return language; }
660 
661     public ScriptMetaData findScript( ParsedScriptUri  parsedUri ) throws  com.sun.star.container.NoSuchElementException,  com.sun.star.lang.WrappedTargetException
662     {
663         ScriptMetaData scriptData = null;
664         Parcel p = null;
665         p = (Parcel)getByName( parsedUri.parcel);
666         scriptData = (ScriptMetaData)p.getByName( parsedUri.function);
667         LogUtils.DEBUG("** found script data for " +  parsedUri.function + " script is " + scriptData );
668         return scriptData;
669 
670     }
671 public  ParsedScriptUri parseScriptUri( String scriptURI ) throws com.sun.star.lang.IllegalArgumentException
672 {
673 
674         XMultiComponentFactory xMcFac = null;
675         XUriReferenceFactory xFac = null;
676 
677         try
678         {
679             xMcFac = m_xCtx.getServiceManager();
680             xFac = ( XUriReferenceFactory )
681                 UnoRuntime.queryInterface( XUriReferenceFactory.class,
682                     xMcFac.createInstanceWithContext(
683                         "com.sun.star.uri.UriReferenceFactory", m_xCtx ) );
684         }
685         catch( com.sun.star.uno.Exception e )
686         {
687             LogUtils.DEBUG("Problems parsing  URL:" + e.toString() );
688             throw new  com.sun.star.lang.IllegalArgumentException( "Problems parsing  URL reason: " + e.toString() );
689         }
690         if ( xFac == null )
691         {
692             LogUtils.DEBUG("Failed to create UrlReference factory");
693             throw new  com.sun.star.lang.IllegalArgumentException( "Failed to create UrlReference factory for url " + scriptURI );
694         }
695 
696         XUriReference uriRef = xFac.parse( scriptURI );
697         XVndSunStarScriptUrl  sfUri = ( XVndSunStarScriptUrl )
698             UnoRuntime.queryInterface( XVndSunStarScriptUrl.class, uriRef );
699 
700         if ( sfUri == null )
701         {
702             LogUtils.DEBUG("Failed to parse url");
703             throw new  com.sun.star.lang.IllegalArgumentException( "Failed to parse url " + scriptURI );
704         }
705 
706         ParsedScriptUri parsedUri = new ParsedScriptUri();
707         // parse language
708         parsedUri.language = sfUri.getParameter("language");
709         parsedUri.function= sfUri.getName();
710         parsedUri.parcel = "";
711 
712         // parse parcel name;
713         StringTokenizer tokenizer = new StringTokenizer( parsedUri.function, "." );
714 
715         if ( tokenizer.hasMoreElements() )
716         {
717             parsedUri.parcel = (String)tokenizer.nextElement();
718             LogUtils.DEBUG("** parcelName = " + parsedUri.parcel );
719         }
720 
721         if ( parsedUri.function != null && ( parsedUri.function.length() > 0 ) )
722         {
723             // strip out parcel name
724             parsedUri.function = parsedUri.function.substring( parsedUri.parcel.length() + 1);
725         }
726 
727         // parse location
728         parsedUri.location = sfUri.getParameter("location");
729 
730         // TODO basic sanity check on language, location, functioname, parcel
731         // should be correct e.g. verified  by MSP and LangProvider by the
732         // time its got to here
733 
734         LogUtils.DEBUG("** location = " + parsedUri.location +
735             "\nfunction = " + parsedUri.function +
736             "\nparcel = " + parsedUri.parcel +
737             "\nlocation = " + parsedUri.location );
738         return parsedUri;
739 }
740 
741 
742 }
743