1 19 20 package org.netbeans.modules.tasklist.usertasks.translators; 21 22 import java.io.BufferedOutputStream ; 23 import java.io.BufferedReader ; 24 import java.io.File ; 25 import java.io.FileOutputStream ; 26 import java.io.IOException ; 27 import java.io.OutputStreamWriter ; 28 import java.io.Reader ; 29 import java.io.StringReader ; 30 import java.io.StringWriter ; 31 import java.io.Writer ; 32 import java.net.URISyntaxException ; 33 import java.net.URL ; 34 import java.text.ParseException ; 35 import java.text.SimpleDateFormat ; 36 import java.util.ArrayList ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.logging.Level ; 40 import net.fortuna.ical4j.data.CalendarOutputter; 41 import net.fortuna.ical4j.model.Calendar; 42 import net.fortuna.ical4j.model.Component; 43 import net.fortuna.ical4j.model.ComponentList; 44 import net.fortuna.ical4j.model.Date; 45 import net.fortuna.ical4j.model.DateTime; 46 import net.fortuna.ical4j.model.Property; 47 import net.fortuna.ical4j.model.PropertyList; 48 import net.fortuna.ical4j.model.ValidationException; 49 import net.fortuna.ical4j.model.component.VToDo; 50 import net.fortuna.ical4j.model.parameter.XParameter; 51 import net.fortuna.ical4j.model.property.Categories; 52 import net.fortuna.ical4j.model.property.Completed; 53 import net.fortuna.ical4j.model.property.Created; 54 import net.fortuna.ical4j.model.property.Description; 55 import net.fortuna.ical4j.model.property.DtStamp; 56 import net.fortuna.ical4j.model.property.DtStart; 57 import net.fortuna.ical4j.model.property.LastModified; 58 import net.fortuna.ical4j.model.property.PercentComplete; 59 import net.fortuna.ical4j.model.property.Priority; 60 import net.fortuna.ical4j.model.property.ProdId; 61 import net.fortuna.ical4j.model.property.RelatedTo; 62 import net.fortuna.ical4j.model.property.Summary; 63 import net.fortuna.ical4j.model.property.Uid; 64 import net.fortuna.ical4j.model.property.Url; 65 import net.fortuna.ical4j.model.property.Version; 66 import net.fortuna.ical4j.model.property.XProperty; 67 68 import org.netbeans.modules.tasklist.core.export.ExportImportFormat; 69 import org.netbeans.modules.tasklist.core.export.ExportImportProvider; 70 import org.netbeans.modules.tasklist.core.export.SaveFilePanel; 71 import org.netbeans.modules.tasklist.core.util.ExtensionFileFilter; 72 import org.netbeans.modules.tasklist.core.util.ObjectList; 73 import org.netbeans.modules.tasklist.core.util.SimpleWizardPanel; 74 import org.netbeans.modules.tasklist.usertasks.options.Settings; 75 import org.netbeans.modules.tasklist.usertasks.UserTaskViewRegistry; 76 import org.netbeans.modules.tasklist.usertasks.model.UserTask; 77 import org.netbeans.modules.tasklist.usertasks.model.UserTaskList; 78 import org.netbeans.modules.tasklist.usertasks.model.Dependency; 79 import org.netbeans.modules.tasklist.usertasks.util.UTUtils; 80 import org.openide.WizardDescriptor; 81 import org.openide.util.NbBundle; 82 83 99 public class ICalExportFormat implements ExportImportFormat { 100 private final static String PRODID = 101 "-//NetBeans User Tasks//NONSGML 1.0//EN"; protected final static String 103 CHOOSE_FILE_PANEL_PROP = "ChooseFilePanel"; 105 private static final String DATEFORMATZ = "yyyyMMdd'T'HHmmss'Z'"; private static final SimpleDateFormat DATEFORMAT = 109 new SimpleDateFormat (DATEFORMATZ); 110 111 117 private static void convertToSystem(Reader r, Writer w) throws 118 IOException { 119 BufferedReader br = new BufferedReader (r); 120 final String EOL = System.getProperty("line.separator"); String line; 122 while ((line = br.readLine()) != null) { 123 w.write(line); 124 w.write(EOL); 125 } 126 } 127 128 131 public ICalExportFormat() { 132 } 133 134 public void doExportImport(ExportImportProvider provider, WizardDescriptor wd) { 135 SaveFilePanel panel = 136 (SaveFilePanel) wd.getProperty(CHOOSE_FILE_PANEL_PROP); 137 try { 138 UserTaskList list = UserTaskViewRegistry.getInstance(). 139 getCurrent().getUserTaskList(); 140 Writer w = new OutputStreamWriter ( 141 new BufferedOutputStream ( 142 new FileOutputStream (panel.getFile())), "UTF-8"); 143 try { 144 writeList(list, w, true); 145 Settings.getDefault().setLastUsedExportFolder( 146 panel.getFile().getParentFile()); 147 } finally { 148 try { 149 w.close(); 150 } catch (IOException e) { 151 UTUtils.LOGGER.log(Level.WARNING, 152 "Error closing file", e); } 154 } 155 } catch (ParseException e) { 156 UTUtils.LOGGER.log(Level.SEVERE, "", e); } catch (URISyntaxException e) { 158 UTUtils.LOGGER.log(Level.SEVERE, "", e); } catch (ValidationException e) { 160 UTUtils.LOGGER.log(Level.SEVERE, "", e); } catch (IOException e) { 162 UTUtils.LOGGER.log(Level.SEVERE, "", e); } 164 } 165 166 public String getName() { 167 return NbBundle.getMessage(ICalExportFormat.class, "iCalExp"); } 169 170 172 public org.openide.WizardDescriptor getWizard() { 173 SaveFilePanel chooseFilePanel = new SaveFilePanel(); 174 SimpleWizardPanel chooseFileWP = new SimpleWizardPanel(chooseFilePanel); 175 chooseFilePanel.setWizardPanel(chooseFileWP); 176 chooseFilePanel.getFileChooser().addChoosableFileFilter( 177 new ExtensionFileFilter( 178 NbBundle.getMessage(XmlExportFormat.class, 179 "IcsFilter"), new String [] {".ics"})); chooseFilePanel.setFile(new File ( 182 Settings.getDefault().getLastUsedExportFolder(), 183 "tasklist.ics")); 185 WizardDescriptor.Iterator iterator = 187 new WizardDescriptor.ArrayIterator(new WizardDescriptor.Panel[] { 188 chooseFileWP 189 }); 190 WizardDescriptor d = new WizardDescriptor(iterator); 191 d.putProperty("WizardPanel_contentData", new String [] { 193 NbBundle.getMessage( 194 XmlExportFormat.class, "ChooseDestination"), } 196 ); String title; 198 title = NbBundle.getMessage(ICalExportFormat.class, "ExportICAL"); d.setTitle(title); d.putProperty(CHOOSE_FILE_PANEL_PROP, chooseFilePanel); 201 d.putProperty("WizardPanel_autoWizardStyle", Boolean.TRUE); d.putProperty("WizardPanel_contentDisplayed", Boolean.TRUE); d.putProperty("WizardPanel_contentNumbered", Boolean.TRUE); d.setTitleFormat(new java.text.MessageFormat ("{0}")); return d; 206 } 207 208 216 public void writeList(UserTaskList list, Writer out, boolean std) 217 throws IOException , ValidationException, URISyntaxException , ParseException { 218 Calendar cal = (Calendar) list.userObject; 219 if (cal == null) 220 cal = new Calendar(); 221 222 Property prop = cal.getProperties().getProperty(Property.PRODID); 223 if (prop == null) { 224 prop = new ProdId(PRODID); 225 cal.getProperties().add(prop); 226 } else { 227 prop.setValue(PRODID); 228 } 229 230 prop = cal.getProperties().getProperty(Property.VERSION); 231 if (prop != null) 232 cal.getProperties().remove(prop); 233 cal.getProperties().add(Version.VERSION_2_0); 234 235 Iterator it = list.getSubtasks().iterator(); 236 int[] p = new int[1]; 237 while (it.hasNext()) { 238 UserTask item = (UserTask) it.next(); 239 writeTask(cal, item, p); 240 } 241 242 final List <String > uids = new ArrayList <String >(); 243 UserTaskList.processDepthFirst( 244 new UserTaskList.UserTaskProcessor() { 245 public void process(UserTask ut) { 246 uids.add(ut.getUID()); 247 } 248 }, list.getSubtasks() 249 ); 250 removeUnusedVToDos(cal, uids); 251 252 if (cal.getComponents().size() == 0) { 254 VToDo td = new VToDo(); 255 td.getProperties().add(new Summary( 256 NbBundle.getMessage(ICalExportFormat.class, 257 "Welcome"))); 259 cal.getComponents().add(td); 260 } 261 262 CalendarOutputter co = new CalendarOutputter(); 263 if (std) { 264 co.output(cal, out); 265 } else { 266 StringWriter sw = new StringWriter (); 267 co.output(cal, sw); 268 StringReader sr = new StringReader (sw.getBuffer().toString()); 269 convertToSystem(sr, out); 270 } 271 } 272 273 279 private static void removeUnusedVToDos(Calendar cal, List uids) { 280 ComponentList cl = cal.getComponents(); 281 Iterator it = cl.iterator(); 282 while (it.hasNext()) { 283 Component c = (Component) it.next(); 284 if (c.getName().equals(Component.VTODO)) { 285 Uid p = (Uid) c.getProperties().getProperty(Property.UID); 286 if (p == null || uids.indexOf(p.getValue()) < 0) 287 it.remove(); 288 } 289 } 290 } 291 292 299 private static VToDo find(Calendar cal, String uid) { 300 ComponentList cl = cal.getComponents().getComponents(Component.VTODO); 301 for (int i = 0; i < cl.size(); i++) { 302 VToDo c = (VToDo) cl.get(i); 303 Uid p = (Uid) c.getProperties().getProperty(Property.UID); 304 if (p != null && p.getValue().equals(uid)) 305 return c; 306 } 307 return null; 308 } 309 310 318 @SuppressWarnings ("unchecked") 319 private void writeTask(Calendar cal, UserTask task, int[] position) 320 throws IOException , URISyntaxException , ParseException , ValidationException { 321 VToDo vtodo = find(cal, task.getUID()); 322 if (vtodo == null) { 323 vtodo = new VToDo(); 324 vtodo.getProperties().add(new Uid(task.getUID())); 325 cal.getComponents().add(position[0], vtodo); 326 } else { 327 cal.getComponents().remove(vtodo); 328 cal.getComponents().add(position[0], vtodo); 329 } 330 position[0]++; 331 332 PropertyList pl = vtodo.getProperties(); 333 Property prop = pl.getProperty(Property.CREATED); 334 if (prop == null) { 335 prop = new Created(); 336 pl.add(prop); 337 } 338 long created = task.getCreatedDate(); 339 DateTime dt = new DateTime(created); 340 dt.setUtc(true); 341 ((Created) prop).setDate(dt); 342 prop.validate(); 343 344 prop = pl.getProperty(Property.DTSTAMP); 346 if (prop == null) { 347 prop = new DtStamp(); 348 pl.add(prop); 349 } 350 ((DtStamp) prop).setDate(dt); 351 352 prop = pl.getProperty(Property.DTSTART); 353 if (task.getStart() != -1) { 354 if (prop == null) { 355 prop = new DtStart(); 356 pl.add(prop); 357 } 358 dt = new DateTime(task.getStart()); 359 dt.setUtc(true); 360 ((DtStart) prop).setDate(dt); 361 prop.validate(); 362 } else { 363 if (prop != null) 364 pl.remove(prop); 365 } 366 367 String desc = task.getSummary(); 369 prop = pl.getProperty(Property.SUMMARY); 370 if (desc != null && desc.length() > 0) { 371 if (prop == null) { 372 prop = new Summary(); 373 pl.add(prop); 374 } 375 prop.setValue(desc); 376 } else { 377 if (prop != null) 378 pl.remove(prop); 379 } 380 381 String details = task.getDetails(); 383 prop = pl.getProperty(Property.DESCRIPTION); 384 if (details != null && details.length() > 0) { 385 if (prop == null) { 386 prop = new Description(); 387 pl.add(prop); 388 } 389 prop.setValue(details); 390 } else { 391 if (prop != null) 392 pl.remove(prop); 393 } 394 395 prop = pl.getProperty(Property.PRIORITY); 397 if (prop != null) 398 pl.remove(prop); 399 if (task.getPriority() != UserTask.MEDIUM) { 400 prop = new Priority(task.getPriority()); 401 pl.add(prop); 402 } 403 404 413 414 416 420 425 426 prop = pl.getProperty(Property.PERCENT_COMPLETE); 427 if (prop == null) { 428 prop = new PercentComplete(); 429 pl.add(prop); 430 } 431 ((PercentComplete) prop).setPercentage(task.getPercentComplete()); 432 433 setXProperty(pl, "X-NETBEANS-VALUES-COMPUTED", "yes", task.isValuesComputed()); 435 436 437 setXProperty(pl, "X-NETBEANS-PROGRESS-COMPUTED", "yes", task.isValuesComputed()); 440 setXProperty(pl, "X-NETBEANS-EFFORT-COMPUTED", "yes", task.isValuesComputed()); 442 setXProperty(pl, "X-NETBEANS-SPENT-TIME-COMPUTED", "yes", task.isValuesComputed()); 444 445 setXProperty(pl, "X-NETBEANS-EFFORT", Integer.toString(task.getEffort()), true); 447 448 setXProperty(pl, "X-NETBEANS-SPENT-TIME", Integer.toString(task.getSpentTime()), true); 450 451 String category = task.getCategory(); 454 prop = pl.getProperty(Property.CATEGORIES); 455 if (category != null && category.length() > 0) { 456 if (prop == null) { 460 prop = new Categories(); 461 pl.add(prop); 462 } 463 ((Categories) prop).setValue(category); } else { 465 if (prop != null) 466 pl.remove(prop); 467 } 468 469 long edited = task.getLastEditedDate(); 472 prop = pl.getProperty(Property.LAST_MODIFIED); 473 if (edited != created) { 474 if (prop == null) { 476 prop = new LastModified(); 477 pl.add(prop); 478 } 479 dt = new DateTime(edited); 480 dt.setUtc(true); 481 ((LastModified) prop).setDate(dt); 482 prop.validate(); 483 } else { 484 if (prop != null) 485 pl.remove(pl); 486 } 487 488 long completed = task.getCompletedDate(); 490 prop = pl.getProperty(Property.COMPLETED); 491 if (completed != 0) { 492 if (prop == null) { 493 prop = new Completed(); 494 pl.add(prop); 495 } 496 dt = new DateTime(task.getCompletedDate()); 497 dt.setUtc(true); 498 ((Completed) prop).setDate(dt); 499 prop.validate(); 500 } else { 501 if (prop != null) 502 pl.remove(prop); 503 } 504 505 URL url = task.getUrl(); 507 prop = pl.getProperty(Property.URL); 508 if (url != null) { 509 if (prop == null) { 510 prop = new Url(); 511 pl.add(prop); 512 } 513 prop.setValue(url.toExternalForm()); 514 } else { 515 if (prop != null) 516 pl.remove(pl); 517 } 518 519 int lineno = task.getLineNumber(); 521 setXProperty(pl, "X-NETBEANS-LINE", Integer.toString(lineno + 1), lineno >= 0); 523 524 setXProperty(pl, "X-NETBEANS-OWNER", task.getOwner(), task.getOwner().length() != 0); 526 527 prop = pl.getProperty(Property.RELATED_TO); 531 if (task.getParent() != null) { 532 if (prop == null) { 533 prop = new RelatedTo(); 534 pl.add(prop); 535 } 536 String parentuid = ((UserTask)task.getParent()).getUID(); 537 prop.setValue(parentuid); 538 } else { 539 if (prop != null) 540 pl.remove(prop); 541 } 542 543 List dep = task.getDependencies(); 544 pl.removeAll(pl.getProperties("X-NETBEANS-DEPENDENCY")); for (int i = 0; i < dep.size(); i++) { 546 Dependency d = (Dependency) dep.get(i); 547 prop = new XProperty("X-NETBEANS-DEPENDENCY"); prop.setValue(d.getDependsOn().getUID()); 549 String t = (d.getType() == Dependency.BEGIN_BEGIN) ? 550 "BEGIN_BEGIN" : "END_BEGIN"; prop.getParameters().add(new XParameter("X-NETBEANS-TYPE", t)); pl.add(prop); 553 } 554 555 ObjectList wks = task.getWorkPeriods(); 556 pl.removeAll(pl.getProperties("X-NETBEANS-WORK-PERIOD")); for (int i = 0; i < wks.size(); i++) { 558 UserTask.WorkPeriod wk = (UserTask.WorkPeriod) wks.get(i); 559 prop = new XProperty("X-NETBEANS-WORK-PERIOD"); String v = DATEFORMAT.format(new java.util.Date (wk.getStart())); 561 prop.getParameters().add(new XParameter( 562 "X-NETBEANS-START", v)); 564 prop.setValue(Integer.toString(wk.getDuration())); 565 pl.add(prop); 566 } 567 568 java.util.Date d = task.getDueDate(); 569 if (d != null) 570 setXProperty(pl, "X-NETBEANS-DUETIME", Long.toString(d.getTime()), true); 572 else 573 setXProperty(pl, "X-NETBEANS-DUETIME", "", false); 575 576 setXProperty(pl, "X-NETBEANS-DUE-SIGNALED", "yes", task.isDueAlarmSent()); 578 579 623 Iterator it = task.getSubtasks().iterator(); 625 while (it.hasNext()) { 626 UserTask subtask = (UserTask)it.next(); 627 writeTask(cal, subtask, position); 628 } 629 } 630 631 640 private static void setXProperty(PropertyList pl, 641 String name, String value, boolean set) throws IOException , 642 URISyntaxException , ParseException { 643 Property prop = pl.getProperty(name); 644 if (set) { 645 if (prop == null) { 646 prop = new XProperty(name); 647 pl.add(prop); 648 } 649 prop.setValue(value); 650 } else { 651 if (prop != null) 652 pl.remove(prop); 653 } 654 } 655 } 656 | Popular Tags |