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.browse;
25 
26 import com.sun.star.beans.XIntrospectionAccess;
27 
28 import com.sun.star.lib.uno.helper.PropertySet;
29 
30 import com.sun.star.uno.UnoRuntime;
31 import com.sun.star.uno.Any;
32 import com.sun.star.uno.AnyConverter;
33 import com.sun.star.uno.Type;
34 import com.sun.star.uno.XComponentContext;
35 
36 
37 import com.sun.star.lang.XMultiComponentFactory;
38 
39 
40 import com.sun.star.script.XInvocation;
41 
42 import com.sun.star.ucb.XSimpleFileAccess;
43 
44 import com.sun.star.script.browse.XBrowseNode;
45 import com.sun.star.script.browse.BrowseNodeTypes;
46 
47 import com.sun.star.script.framework.provider.ScriptProvider;
48 import com.sun.star.script.framework.log.LogUtils;
49 import com.sun.star.script.framework.container.ScriptMetaData;
50 import com.sun.star.script.framework.container.ScriptEntry;
51 import com.sun.star.script.framework.container.Parcel;
52 import com.sun.star.script.framework.container.ParcelContainer;
53 import com.sun.star.script.framework.browse.DialogFactory;
54 
55 import java.util.*;
56 import javax.swing.JOptionPane;
57 
58 public class ParcelBrowseNode extends PropertySet
59     implements XBrowseNode, XInvocation
60 {
61     private ScriptProvider provider;
62     //private RootBrowseNode parent;
63     private Collection browsenodes;
64     private String name;
65     private ParcelContainer container;
66     private Parcel parcel;
67     public boolean deletable = true;
68     public boolean editable  = false;
69     public boolean creatable = false;
70     public boolean renamable = true;
71 
ParcelBrowseNode( ScriptProvider provider, ParcelContainer container, String parcelName )72     public ParcelBrowseNode( ScriptProvider provider, ParcelContainer container, String parcelName ) {
73         this.provider = provider;
74         this.name = parcelName;
75         this.container = container;
76 
77         // TODO decide whether exception is propagated out or not
78         try
79         {
80             this.parcel = (Parcel)this.container.getByName( parcelName );
81         }
82         catch ( Exception e )
83         {
84 
85             LogUtils.DEBUG("** Exception: " + e );
86             LogUtils.DEBUG(" ** Failed to get parcel named " +
87                            parcelName + " from container" );
88         }
89         registerProperty("Deletable", new Type(boolean.class),
90             (short)0, "deletable");
91         registerProperty("Editable", new Type(boolean.class),
92             (short)0, "editable");
93         registerProperty("Creatable", new Type(boolean.class),
94             (short)0, "creatable");
95         registerProperty("Renamable", new Type(boolean.class),
96             (short)0, "renamable");
97         if (provider.hasScriptEditor() == true)
98         {
99             this.creatable = true;
100         }
101 
102         String parcelDirUrl = parcel.getPathToParcel();
103         XComponentContext xCtx = provider.getScriptingContext().getComponentContext();
104         XMultiComponentFactory xFac = xCtx.getServiceManager();
105         try
106         {
107             XSimpleFileAccess xSFA = ( XSimpleFileAccess)
108                 UnoRuntime.queryInterface( XSimpleFileAccess.class,
109                     xFac.createInstanceWithContext(
110                         "com.sun.star.ucb.SimpleFileAccess",
111                         xCtx ) );
112             if ( xSFA != null && ( xSFA.isReadOnly( parcelDirUrl ) ||
113                 container.isUnoPkg() ) )
114             {
115                 deletable = false;
116                 editable  = false;
117                 creatable = false;
118                 renamable = false;
119             }
120         }
121         catch ( com.sun.star.uno.Exception e )
122         {
123             // TODO propagate potential errors
124             // Pthrow new com.sun.star.uno.RuntimeException( e.toString() );
125             LogUtils.DEBUG( "Caught exception creating ParcelBrowseNode " + e );
126             LogUtils.DEBUG( LogUtils.getTrace( e ) );
127         }
128 
129     }
130 
getName()131     public String getName() {
132         return parcel.getName();
133     }
134 
getChildNodes()135     public XBrowseNode[] getChildNodes() {
136         try
137         {
138 
139             if ( hasChildNodes() )
140             {
141                 String[] names = parcel.getElementNames();
142                 browsenodes = new ArrayList( names.length );
143 
144                 for ( int index = 0; index < names.length; index++ )
145                 {
146                     browsenodes.add( new ScriptBrowseNode( provider, parcel, names[ index ] ));
147                 }
148             }
149             else
150             {
151                 LogUtils.DEBUG("ParcelBrowseNode.getChildeNodes no children " );
152                 return new XBrowseNode[0];
153             }
154         }
155         catch ( Exception e )
156         {
157             LogUtils.DEBUG("Failed to getChildeNodes, exception: " + e );
158             LogUtils.DEBUG( LogUtils.getTrace( e ) );
159             return new XBrowseNode[0];
160         }
161         return (XBrowseNode[])browsenodes.toArray(new XBrowseNode[0]);
162     }
163 
hasChildNodes()164     public boolean hasChildNodes() {
165         if ( container != null && container.hasByName( getName() ) && parcel != null )
166         {
167             return parcel.hasElements();
168         }
169 
170         return false;
171     }
172 
getType()173     public short getType() {
174         return BrowseNodeTypes.CONTAINER;
175     }
176 
toString()177     public String toString()
178     {
179         return getName();
180     }
181 
182     // implementation of XInvocation interface
getIntrospection()183     public XIntrospectionAccess getIntrospection() {
184         return null;
185     }
186 
invoke(String aFunctionName, Object[] aParams, short[][] aOutParamIndex, Object[][] aOutParam)187     public Object invoke(String aFunctionName, Object[] aParams,
188                          short[][] aOutParamIndex, Object[][] aOutParam)
189         throws com.sun.star.lang.IllegalArgumentException,
190                com.sun.star.script.CannotConvertException,
191                com.sun.star.reflection.InvocationTargetException
192     {
193         LogUtils.DEBUG("ParcelBrowseNode invoke for " + aFunctionName );
194         // Initialise the out parameters - not used but prevents error in
195         // UNO bridge
196         aOutParamIndex[0] = new short[0];
197         aOutParam[0] = new Object[0];
198 
199         Any result = new Any(new Type(Boolean.class), Boolean.TRUE);
200 
201         if (aFunctionName.equals("Creatable"))
202         {
203             try
204             {
205                 String newName;
206 
207                 if (aParams == null || aParams.length < 1 ||
208                     AnyConverter.isString(aParams[0]) == false)
209                 {
210                     String prompt = "Enter name for new Script";
211                     String title = "Create Script";
212 
213                     // try to get a DialogFactory instance, if it fails
214                     // just use a Swing JOptionPane to prompt for the name
215                     try
216                     {
217                         DialogFactory dialogFactory =
218                             DialogFactory.getDialogFactory();
219 
220                         newName = dialogFactory.showInputDialog(title, prompt);
221                     }
222                     catch (Exception e)
223                     {
224                         newName = JOptionPane.showInputDialog(null, prompt, title,
225                             JOptionPane.QUESTION_MESSAGE);
226                     }
227                 }
228                 else {
229                     newName = (String) AnyConverter.toString(aParams[0]);
230                 }
231 
232                 if ( newName == null || newName.equals(""))
233                 {
234                     result =  new Any(new Type(Boolean.class), Boolean.FALSE);
235                 }
236                 else
237                 {
238                     String source = new String(provider.getScriptEditor().getTemplate().getBytes());
239                     String languageName = newName + "." + provider.getScriptEditor().getExtension();
240                     String language = container.getLanguage();
241 
242                     ScriptEntry entry = new ScriptEntry( language, languageName, languageName, "", new HashMap() );
243 
244                     Parcel parcel = (Parcel)container.getByName( getName() );
245                     ScriptMetaData data = new ScriptMetaData( parcel, entry, source );
246                     parcel.insertByName( languageName, data );
247 
248                     ScriptBrowseNode sbn = new ScriptBrowseNode( provider, parcel, languageName );
249 
250 					if(browsenodes==null)
251 					{
252 							LogUtils.DEBUG("browsenodes null!!");
253 							browsenodes = new ArrayList(4);
254 					}
255                     browsenodes.add(sbn);
256 
257                     result = new Any(new Type(XBrowseNode.class), sbn);
258                 }
259             }
260             catch (Exception e)
261             {
262 		LogUtils.DEBUG("ParcelBrowseNode[create] failed with: " + e );
263                 LogUtils.DEBUG( LogUtils.getTrace( e ) );
264                 result = new Any(new Type(Boolean.class), Boolean.FALSE);
265 
266                 // throw new com.sun.star.reflection.InvocationTargetException(
267                 //     "Error creating script: " + e.getMessage());
268             }
269         }
270         else if (aFunctionName.equals("Deletable"))
271         {
272             try
273             {
274                 if ( container.deleteParcel(getName()) )
275                 {
276                     result = new Any(new Type(Boolean.class), Boolean.TRUE);
277                 }
278                 else
279                 {
280                     result = new Any(new Type(Boolean.class), Boolean.FALSE);
281                 }
282             }
283             catch (Exception e)
284             {
285                 result =  new Any(new Type(Boolean.class), Boolean.FALSE);
286 
287                 // throw new com.sun.star.reflection.InvocationTargetException(
288                 //     "Error deleting parcel: " + e.getMessage());
289             }
290         }
291         else if (aFunctionName.equals("Renamable"))
292         {
293             String newName = null;
294             try
295             {
296 
297                 if (aParams == null || aParams.length < 1 ||
298                     AnyConverter.isString(aParams[0]) == false)
299                 {
300                     String prompt = "Enter new name for Library";
301                     String title = "Rename Library";
302 
303                     // try to get a DialogFactory instance, if it fails
304                     // just use a Swing JOptionPane to prompt for the name
305                     try
306                     {
307                         DialogFactory dialogFactory =
308                             DialogFactory.getDialogFactory();
309 
310                         newName = dialogFactory.showInputDialog(title, prompt);
311                     }
312                     catch (Exception e)
313                     {
314                         newName = JOptionPane.showInputDialog(null, prompt, title,
315                             JOptionPane.QUESTION_MESSAGE);
316                     }
317                 }
318                 else {
319                     newName = (String) AnyConverter.toString(aParams[0]);
320                 }
321                 container.renameParcel( getName(), newName );
322                 Parcel p = (Parcel)container.getByName( newName );
323                 if(browsenodes == null )
324                 {
325                     getChildNodes();
326                 }
327                 ScriptBrowseNode[] childNodes = (ScriptBrowseNode[])browsenodes.toArray(new ScriptBrowseNode[0]);
328 
329                 for ( int index = 0; index < childNodes.length; index++ )
330                 {
331                     childNodes[ index ].updateURI( p );
332                 }
333                 result = new Any(new Type(XBrowseNode.class), this);
334             }
335             catch (Exception e)
336             {
337                 result =  new Any(new Type(Boolean.class), Boolean.FALSE);
338 
339                 // throw new com.sun.star.reflection.InvocationTargetException(
340                 //     "Error renaming parcel: " + e.getMessage());
341             }
342         }
343 
344         else {
345             throw new com.sun.star.lang.IllegalArgumentException(
346                 "Function " + aFunctionName + " not supported.");
347         }
348 
349         return result;
350     }
351 
setValue(String aPropertyName, Object aValue)352     public void setValue(String aPropertyName, Object aValue)
353         throws com.sun.star.beans.UnknownPropertyException,
354                com.sun.star.script.CannotConvertException,
355                com.sun.star.reflection.InvocationTargetException
356     {
357     }
358 
getValue(String aPropertyName)359     public Object getValue(String aPropertyName)
360         throws com.sun.star.beans.UnknownPropertyException
361     {
362         return null;
363     }
364 
hasMethod(String aName)365     public boolean hasMethod(String aName) {
366         return false;
367     }
368 
hasProperty(String aName)369     public boolean hasProperty(String aName) {
370         return false;
371     }
372 }
373