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.wizards.web.data; 24 25 import java.io.File; 26 import java.io.FileNotFoundException; 27 28 import org.w3c.dom.Node; 29 30 import com.sun.star.beans.PropertyValue; 31 import com.sun.star.document.MacroExecMode; 32 import com.sun.star.document.UpdateDocMode; 33 import com.sun.star.document.XDocumentProperties; 34 import com.sun.star.document.XDocumentPropertiesSupplier; 35 import com.sun.star.frame.XComponentLoader; 36 import com.sun.star.frame.XDesktop; 37 import com.sun.star.lang.XComponent; 38 import com.sun.star.lang.XMultiServiceFactory; 39 import com.sun.star.uno.UnoRuntime; 40 import com.sun.star.util.DateTime; 41 import com.sun.star.wizards.common.Desktop; 42 import com.sun.star.wizards.common.FileAccess; 43 import com.sun.star.wizards.common.JavaTools; 44 import com.sun.star.wizards.common.Properties; 45 import com.sun.star.wizards.common.PropertyNames; 46 import com.sun.star.wizards.common.XMLHelper; 47 import com.sun.star.wizards.common.XMLProvider; 48 import com.sun.star.wizards.document.OfficeDocument; 49 import com.sun.star.wizards.ui.event.Task; 50 51 /** 52 * About the member fields Title, Decription and Author: 53 * There is an ambiguicy in handling these fields. 54 * On the one hand, the user can set those fields to a custom value, 55 * relevant only for the web-wizard. 56 * On the other-hand, the web-wizard can read those fields automatically 57 * from SO documents. 58 * In order to avoid conflict by saving, I use two fields: "cp_title", which 59 * should be read from the configuratin (saved session), and "title" which is 60 * the value read from the document. 61 * The *cp_title* "overrides" *title*, if exists. if not, *title* is used. 62 * The same is valid for *description* and *author*. 63 * @author rpiterman 64 */ 65 public class CGDocument extends ConfigSetItem implements XMLProvider 66 { 67 68 public static final int PAGE_TYPE_UNKNOWN = 0; 69 public static final int PAGE_TYPE_PAGE = 1; 70 public static final int PAGE_TYPE_SLIDE = 2; 71 public String cp_Title = PropertyNames.EMPTY_STRING; 72 public String cp_Description = PropertyNames.EMPTY_STRING; 73 public String cp_URL; 74 public String cp_Author = PropertyNames.EMPTY_STRING; 75 public String cp_Exporter; 76 /** 77 * the destination filename to which this 78 * document will be exported to. 79 */ 80 public String localFilename = PropertyNames.EMPTY_STRING; 81 public String urlFilename = PropertyNames.EMPTY_STRING; 82 public String title = PropertyNames.EMPTY_STRING; 83 public String description = PropertyNames.EMPTY_STRING; 84 public String author = PropertyNames.EMPTY_STRING; 85 public DateTime createDate; 86 public DateTime updateDate; 87 public int sizeBytes = -1; 88 public int pages = -1; 89 /** 90 * The contents subdirectory name in which the document is in. 91 * This subdirectory will be created in the content's "docs" 92 * subdirectory. 93 */ 94 public String dirName; 95 /** 96 * contains an identifier of the type of this document. 97 */ 98 public String appType; 99 public PropertyValue[] mediaDescriptor; 100 /** 101 * Is this document an original SO Document (different versions). 102 */ 103 public boolean isSODocument; 104 /** 105 * can this document be opend through SO? 106 */ 107 public boolean isSOOpenable; 108 /** 109 * This flag is set to true after the validate method is called. 110 */ 111 public boolean valid = false; 112 public String targetTypeName; 113 CGDocument()114 public CGDocument() 115 { 116 } 117 CGDocument(String url, XMultiServiceFactory xmsf, Task task)118 public CGDocument(String url, XMultiServiceFactory xmsf, Task task) throws Exception 119 { 120 cp_URL = getSettings().getFileAccess(xmsf).getURL(url); 121 if (task == null) 122 { 123 task = new Task(PropertyNames.EMPTY_STRING, PropertyNames.EMPTY_STRING, 5); 124 } 125 validate(xmsf, task); 126 } 127 128 /** 129 * the task will advance 5 times during validate. 130 * @param xmsf 131 * @param task 132 * @throws Exception 133 */ validate(XMultiServiceFactory xmsf, Task task)134 public void validate(XMultiServiceFactory xmsf, Task task) 135 throws FileNotFoundException, 136 IllegalArgumentException, 137 Exception 138 { 139 140 if (!getSettings().getFileAccess(xmsf).exists(cp_URL, false)) 141 { 142 throw new FileNotFoundException("The given URL does not point to a file"); 143 } 144 if (getSettings().getFileAccess(xmsf).isDirectory(cp_URL)) 145 { 146 throw new IllegalArgumentException("The given URL points to a directory"); //create a TypeDetection service 147 } 148 mediaDescriptor = OfficeDocument.getFileMediaDecriptor(xmsf, cp_URL); 149 150 task.advance(true); //1 151 152 //System.out.println(Properties.getPropertyValue(mediaDescriptor,"UIName")); 153 154 analyzeFileType(mediaDescriptor); 155 156 task.advance(true); //2 157 158 String path = getSettings().getFileAccess(xmsf).getPath(cp_URL, PropertyNames.EMPTY_STRING); 159 localFilename = FileAccess.getFilename(path, File.separator); 160 161 /* if the type is a star office convertable document 162 * We try to open the document to get some properties 163 */ 164 165 XDocumentProperties xProps = null; 166 167 task.advance(true); //3 168 169 if (isSOOpenable) 170 { // for documents which are openable through SO, use DocumentProperties service. 171 XDesktop desktop = Desktop.getDesktop(xmsf); 172 PropertyValue[] props = new PropertyValue[3]; 173 props[0] = Properties.createProperty("Hidden", Boolean.TRUE); 174 props[1] = Properties.createProperty("MacroExecutionMode", new Short(MacroExecMode.NEVER_EXECUTE)); 175 props[2] = Properties.createProperty("UpdateDocMode", new Short(UpdateDocMode.NO_UPDATE)); 176 XComponent component = UnoRuntime.queryInterface(XComponentLoader.class, desktop).loadComponentFromURL(cp_URL, "_default", 0, props); 177 xProps = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, component).getDocumentProperties(); 178 } 179 180 task.advance(true); //4 181 182 //now use the object to read some document properties. 183 if (xProps != null) 184 { 185 title = xProps.getTitle(); 186 description = xProps.getDescription(); 187 author = xProps.getAuthor(); 188 createDate = xProps.getCreationDate(); 189 updateDate = xProps.getModificationDate(); 190 } 191 else 192 { //get some information from OS. 193 title = localFilename; 194 updateDate = getSettings().getFileAccess(xmsf).getLastModified(cp_URL); 195 } 196 197 task.advance(true); //5 198 199 valid = true; 200 201 if (cp_Title.equals(PropertyNames.EMPTY_STRING)) 202 { 203 cp_Title = title; 204 } 205 if (cp_Title.equals(PropertyNames.EMPTY_STRING)) 206 { 207 cp_Title = localFilename; 208 } 209 if (cp_Description.equals(PropertyNames.EMPTY_STRING)) 210 { 211 cp_Description = description; 212 } 213 if (cp_Author.equals(PropertyNames.EMPTY_STRING)) 214 { 215 cp_Author = author; 216 } 217 if (cp_Exporter == null || cp_Exporter.equals(PropertyNames.EMPTY_STRING)) 218 { 219 cp_Exporter = (String) getSettings().cp_Exporters.getKey( 220 getSettings().getExporters(appType)[0]); 221 } 222 } 223 224 /** 225 * Analyzes a type-detection string, returned from the TypeDetection service, 226 * and sets the appType, isSOOpenable and isSODocument members. 227 */ analyzeFileType(PropertyValue[] mediaDesc)228 private void analyzeFileType(PropertyValue[] mediaDesc) 229 { 230 231 if (mediaDesc == null) 232 { 233 } 234 235 String media = (mediaDesc == null) 236 ? PropertyNames.EMPTY_STRING : (String) Properties.getPropertyValue(mediaDescriptor, PropertyNames.PROPERTY_NAME); 237 appType = getDocType(media); 238 239 //System.out.println(appType); 240 241 isSOOpenable = 242 (appType.equals(TypeDetection.WRITER_DOC) || appType.equals(TypeDetection.CALC_DOC) || appType.equals(TypeDetection.IMPRESS_DOC) || appType.equals(TypeDetection.DRAW_DOC)) || appType.equals(TypeDetection.HTML_DOC); 243 244 // String[] parts = media.split("_"); // line removed because of compatibility to JDK13 245 String[] parts = JavaTools.ArrayoutofString(media, "_"); 246 247 248 isSODocument = parts.length >= 2 && isSOOpenable && (parts[1].startsWith("Star")); 249 250 } 251 252 /** 253 * @param media is the media description string returned by an UNO TypeDetection object. 254 * @return one of the constants in the interface TypeDetection. 255 * 256 */ getDocType(String media)257 private String getDocType(String media) 258 { 259 if (media.equals(PropertyNames.EMPTY_STRING)) 260 { 261 return TypeDetection.NO_TYPE; 262 } 263 if (media.startsWith("writer")) 264 { 265 if (media.startsWith("writer_web_HTML")) 266 { 267 return TypeDetection.HTML_DOC; 268 } 269 else 270 { 271 return TypeDetection.WRITER_DOC; 272 } 273 } 274 else if (media.startsWith("calc")) 275 { 276 return TypeDetection.CALC_DOC; 277 } 278 else if (media.startsWith("draw")) 279 { 280 return TypeDetection.DRAW_DOC; 281 } 282 else if (media.startsWith("impress")) 283 { 284 return TypeDetection.IMPRESS_DOC; 285 } 286 else if (media.startsWith("pdf")) 287 { 288 return TypeDetection.PDF_DOC; 289 } 290 else if (media.startsWith("gif") || media.startsWith("jpg")) 291 { 292 return TypeDetection.WEB_GRAPHICS; 293 } 294 else if (media.startsWith("wav")) 295 { 296 return TypeDetection.SOUND_FILE; 297 } 298 else 299 { 300 return TypeDetection.NO_TYPE; 301 } 302 } 303 createDOM(Node parent)304 public Node createDOM(Node parent) 305 { 306 CGDesign d = getSettings().cp_DefaultSession.cp_Design; 307 CGExporter exp = (CGExporter) getSettings().cp_Exporters.getElement(cp_Exporter); 308 309 return XMLHelper.addElement(parent, "document", 310 new String[] 311 { 312 "title", "description", "author", "format", "filename", "create-date", "update-date", "pages", "size", "icon", "dir", "fn" 313 }, 314 new String[] 315 { 316 d.cp_DisplayTitle ? cp_Title : PropertyNames.EMPTY_STRING, 317 d.cp_DisplayDescription ? cp_Description : PropertyNames.EMPTY_STRING, 318 d.cp_DisplayAuthor ? cp_Author : PropertyNames.EMPTY_STRING, 319 d.cp_DisplayFileFormat ? getTargetTypeName(exp) : PropertyNames.EMPTY_STRING, 320 d.cp_DisplayFilename ? localFilename : PropertyNames.EMPTY_STRING, 321 d.cp_DisplayCreateDate ? createDate() : PropertyNames.EMPTY_STRING, 322 d.cp_DisplayUpdateDate ? updateDate() : PropertyNames.EMPTY_STRING, 323 d.cp_DisplayPages && (pages > -1) ? PropertyNames.EMPTY_STRING + pages() : PropertyNames.EMPTY_STRING, //TODO when do i calculate pages? 324 d.cp_DisplaySize ? sizeKB() : PropertyNames.EMPTY_STRING,//TODO when do i calculate size? 325 d.cp_DisplayFormatIcon ? getIcon(exp) : PropertyNames.EMPTY_STRING, 326 dirName, urlFilename 327 }); 328 } 329 updateDate()330 private String updateDate() 331 { 332 if (this.updateDate == null) 333 { 334 return PropertyNames.EMPTY_STRING; 335 } 336 return getSettings().formatter.formatCreated(this.updateDate); 337 } 338 createDate()339 private String createDate() 340 { 341 if (this.createDate == null) 342 { 343 return PropertyNames.EMPTY_STRING; 344 } 345 return getSettings().formatter.formatCreated(this.createDate); 346 } 347 sizeKB()348 private String sizeKB() 349 { 350 if (sizeBytes == -1) 351 { 352 return PropertyNames.EMPTY_STRING; 353 } 354 else 355 { 356 return getSettings().formatter.formatFileSize(sizeBytes); 357 } 358 } 359 pages()360 private String pages() 361 { 362 return pages == -1 ? PropertyNames.EMPTY_STRING 363 : JavaTools.replaceSubString(pagesTemplate(), PropertyNames.EMPTY_STRING + pages, "%NUMBER"); 364 } 365 pagesTemplate()366 private String pagesTemplate() 367 { 368 int pagesType = ((CGExporter) getSettings().cp_Exporters.getElement(cp_Exporter)).cp_PageType; 369 switch (pagesType) 370 { 371 case PAGE_TYPE_UNKNOWN: 372 return PropertyNames.EMPTY_STRING; 373 case PAGE_TYPE_PAGE: 374 return getSettings().resources[CGSettings.RESOURCE_PAGES_TEMPLATE]; 375 case PAGE_TYPE_SLIDE: 376 return getSettings().resources[CGSettings.RESOURCE_SLIDES_TEMPLATE]; 377 default: 378 return PropertyNames.EMPTY_STRING; 379 } 380 } 381 getTargetTypeName(CGExporter exp)382 private String getTargetTypeName(CGExporter exp) 383 { 384 return (exp.targetTypeName.equals(PropertyNames.EMPTY_STRING)) 385 ? (String) Properties.getPropertyValue(mediaDescriptor, "UIName") 386 : exp.targetTypeName; 387 } 388 getIcon(CGExporter exporter)389 private String getIcon(CGExporter exporter) 390 { 391 return exporter.cp_Icon.equals(PropertyNames.EMPTY_STRING) ? getIcon(this.appType) : exporter.cp_Icon; 392 } 393 getIcon(String appType)394 private String getIcon(String appType) 395 { 396 //System.out.println("Getting Icon for: " + appType); 397 return appType + ".gif"; 398 } 399 400 /** 401 * This method is used by the DataAware model 402 * and returns the index of the exporter of 403 * this document, <b>in the list of the 404 * exporters available for this type of document</b> 405 * @return 406 */ getExporter()407 public short[] getExporter() 408 { 409 return new short[] 410 { 411 getExporterIndex() 412 }; 413 } 414 415 /** 416 * @see getExporter() 417 */ setExporter(short[] exporter_)418 public void setExporter(short[] exporter_) 419 { 420 Object exp = getSettings().getExporters(appType)[exporter_[0]]; 421 cp_Exporter = (String) getSettings().cp_Exporters.getKey(exp); 422 } 423 424 /** 425 * @see getExporter() 426 * @return 427 */ getExporterIndex()428 private short getExporterIndex() 429 { 430 if (cp_Exporter == null) 431 { 432 return 0; 433 } 434 Object exporter = getSettings().cp_Exporters.getElement(cp_Exporter); 435 Object[] exporters = getSettings().getExporters(appType); 436 for (short i = 0; i < exporters.length; i++) 437 { 438 if (exporters[i] == exporter) 439 { 440 return i; 441 } 442 } 443 return -1; 444 } 445 toString()446 public String toString() 447 { 448 return localFilename; 449 } 450 } 451