1 19 20 package org.netbeans.modules.tasklist.usertasks.translators; 21 22 import java.io.BufferedReader ; 23 import java.io.File ; 24 import java.io.FileInputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.InputStreamReader ; 28 import java.io.Reader ; 29 import java.io.StringReader ; 30 import java.io.StringWriter ; 31 import java.io.Writer ; 32 import java.net.MalformedURLException ; 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 41 import javax.swing.filechooser.FileSystemView ; 42 import net.fortuna.ical4j.data.CalendarBuilder; 43 import net.fortuna.ical4j.data.ParserException; 44 import net.fortuna.ical4j.model.Calendar; 45 import net.fortuna.ical4j.model.CategoryList; 46 import net.fortuna.ical4j.model.Component; 47 import net.fortuna.ical4j.model.Parameter; 48 import net.fortuna.ical4j.model.ParameterList; 49 import net.fortuna.ical4j.model.Property; 50 import net.fortuna.ical4j.model.PropertyList; 51 import net.fortuna.ical4j.model.property.Categories; 52 import net.fortuna.ical4j.model.property.DateProperty; 53 import net.fortuna.ical4j.model.property.PercentComplete; 54 import net.fortuna.ical4j.model.property.Priority; 55 import net.fortuna.ical4j.util.CompatibilityHints; 56 57 import org.netbeans.modules.tasklist.core.export.ExportImportFormat; 58 import org.netbeans.modules.tasklist.core.export.ExportImportProvider; 59 import org.netbeans.modules.tasklist.core.export.OpenFilePanel; 60 import org.netbeans.modules.tasklist.core.util.ExtensionFileFilter; 61 import org.netbeans.modules.tasklist.core.util.SimpleWizardPanel; 62 import org.netbeans.modules.tasklist.usertasks.util.TreeAbstraction; 63 import org.netbeans.modules.tasklist.usertasks.util.UTUtils; 64 import org.netbeans.modules.tasklist.usertasks.model.UserTask; 65 import org.netbeans.modules.tasklist.usertasks.model.UserTaskList; 66 import org.netbeans.modules.tasklist.usertasks.UserTaskView; 67 import org.netbeans.modules.tasklist.usertasks.model.Dependency; 68 import org.netbeans.modules.tasklist.usertasks.util.UnaryFunction; 69 import org.openide.DialogDisplayer; 70 import org.openide.NotifyDescriptor; 71 import org.openide.WizardDescriptor; 72 import org.openide.filesystems.FileObject; 73 import org.openide.filesystems.URLMapper; 74 import org.openide.text.Line; 75 import org.openide.util.NbBundle; 76 77 97 public class ICalImportFormat implements ExportImportFormat { 98 protected final static String 99 CHOOSE_FILE_PANEL_PROP = "ChooseFilePanel"; 101 private static final String DATEFORMATZ = "yyyyMMdd'T'HHmmss'Z'"; private static final SimpleDateFormat formatter = 103 new SimpleDateFormat (DATEFORMATZ); 104 105 106 private static class Dep { 107 108 public int type; 109 110 111 public UserTask ut; 112 113 114 public String dependsOn; 115 } 116 117 123 private static void convertToRFC2445(Reader r, Writer w) throws 124 IOException { 125 BufferedReader br = new BufferedReader (r); 126 String line; 127 while ((line = br.readLine()) != null) { 128 w.write(line); 129 w.write("\r\n"); 130 } 131 } 132 133 139 public static void read(final UserTaskList utl, InputStream is) throws 140 IOException , ParserException { 141 CompatibilityHints.setHintEnabled( 142 CompatibilityHints.KEY_RELAXED_UNFOLDING, true); 143 CompatibilityHints.setHintEnabled( 144 CompatibilityHints.KEY_RELAXED_VALIDATION, true); 145 CompatibilityHints.setHintEnabled( 146 CompatibilityHints.KEY_RELAXED_PARSING, true); 147 CalendarBuilder cb = new MyCalendarBuilder(); 148 149 List <Dep> dependencies = new ArrayList <Dep>(); 151 152 Reader r = new InputStreamReader (is, "UTF-8"); 153 StringWriter w = new StringWriter (); 154 convertToRFC2445(r, w); 155 r = new StringReader (w.getBuffer().toString()); 156 157 Calendar cal = cb.build(r); 158 for (Iterator i = cal.getComponents().iterator(); i.hasNext();) { 159 Component component = (Component) i.next(); 160 if (component.getName().equals(Component.VTODO)) { 161 readVTODO(utl, component, dependencies); 162 } 163 } 164 165 for (int i = 0; i < dependencies.size(); i++) { 167 Dep d = (Dep) dependencies.get(i); 168 UserTask ut = utl.findItem( 169 utl.getSubtasks().iterator(), d.dependsOn); 170 if (ut != null) { 171 d.ut.getDependencies().add(new Dependency(ut, d.type)); 172 } 173 } 174 175 dependencies.clear(); 176 177 TreeAbstraction tree = new TreeAbstraction() { 178 public Object getChild(Object obj, int index) { 179 if (obj instanceof UserTaskList) { 180 return ((UserTaskList) obj).getSubtasks().get(index); 181 } else { 182 return ((UserTask) obj).getSubtasks().get(index); 183 } 184 } 185 public int getChildCount(Object obj) { 186 if (obj instanceof UserTaskList) { 187 return ((UserTaskList) obj).getSubtasks().size(); 188 } else { 189 return ((UserTask) obj).getSubtasks().size(); 190 } 191 } 192 public Object getRoot() { 193 return utl; 194 } 195 }; 196 UTUtils.processDepthFirst(tree, new UnaryFunction() { 197 public Object compute(Object obj) { 198 if (obj instanceof UserTask) { 199 ((UserTask) obj).setUpdateLastModified(true); 200 } 201 return null; 202 } 203 }); 204 utl.userObject = cal; 205 } 206 207 public void doExportImport(ExportImportProvider provider, WizardDescriptor wd) { 208 OpenFilePanel panel = 209 (OpenFilePanel) wd.getProperty(CHOOSE_FILE_PANEL_PROP); 210 File p = panel.getFile(); 211 if (p == null || !p.exists()) { 212 DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( 213 NbBundle.getMessage(ICalImportFormat.class, 214 "FileDoesNotExist"), NotifyDescriptor.ERROR_MESSAGE)); 216 return; 217 } 218 219 UserTaskView view = (UserTaskView) provider; 220 UserTaskList utl = (UserTaskList) view.getUserTaskList(); 221 222 InputStream is; 223 try { 224 is = new FileInputStream (panel.getFile()); 225 } catch (IOException e) { 226 UTUtils.LOGGER.log(Level.SEVERE, "", e); return; 228 } 229 230 CalendarBuilder cb = new MyCalendarBuilder(); 231 232 try { 233 read(utl, is); 234 } catch (ParserException e) { 235 UTUtils.LOGGER.log(Level.SEVERE, "", e); return; 237 } catch (IOException e) { 238 UTUtils.LOGGER.log(Level.SEVERE, "", e); return; 240 } 241 } 242 243 250 private static void readVTODO(UserTaskList utl, Component cmp, 251 List <Dep> dependencies) { 252 PropertyList pl = cmp.getProperties(); 253 Property prop = pl.getProperty(Property.SUMMARY); 254 String summary = (prop == null) ? "" : prop.getValue(); UserTask ut = new UserTask(summary, utl); 256 ut.setUpdateLastModified(false); 257 258 prop = pl.getProperty(Property.CREATED); 259 if (prop != null) 260 ut.setCreatedDate(((DateProperty) prop).getDate().getTime()); 261 262 prop = pl.getProperty(Property.UID); 263 if (prop != null) 264 ut.setUID(prop.getValue()); 265 266 prop = pl.getProperty(Property.DTSTART); 267 if (prop != null) 268 ut.setStartDate(((DateProperty) prop).getDate()); 269 270 prop = pl.getProperty(Property.PERCENT_COMPLETE); 271 if (prop != null) 272 ut.setPercentComplete(((PercentComplete) prop).getPercentage()); 273 274 prop = pl.getProperty("X-NETBEANS-OWNER"); if (prop != null) 276 ut.setOwner(prop.getValue()); 277 278 prop = pl.getProperty(Property.PRIORITY); 279 if (prop != null) { 280 int level = ((Priority) prop).getLevel(); 281 if (level < 0) 282 level = UserTask.MEDIUM; else if (level == 0) 284 level = UserTask.MEDIUM; 285 else if (level > UserTask.LOW) 286 level = UserTask.LOW; 287 ut.setPriority(level); 288 } 289 290 prop = pl.getProperty("X-NETBEANS-EFFORT"); if (prop != null) { 292 try { 293 ut.setEffort(Integer.parseInt(prop.getValue())); 294 } catch (NumberFormatException e) { 295 UTUtils.LOGGER.log(Level.SEVERE, "", e); } 297 } 298 299 prop = pl.getProperty("X-NETBEANS-SPENT-TIME"); if (prop != null) { 301 try { 302 ut.setSpentTime(Integer.parseInt(prop.getValue())); 303 } catch (NumberFormatException e) { 304 UTUtils.LOGGER.log(Level.SEVERE, "", e); } 306 } 307 308 prop = pl.getProperty(Property.CATEGORIES); 309 if (prop != null) { 310 CategoryList cl = ((Categories) prop).getCategories(); 311 Iterator it = cl.iterator(); 312 StringBuffer category = new StringBuffer (ut.getCategory()); 313 while (it.hasNext()) { 314 if (category.length() > 0) 315 category.append(", "); category.append((String ) it.next()); 317 } 318 ut.setCategory(category.toString()); 319 } 320 321 prop = pl.getProperty(Property.DESCRIPTION); 322 if (prop != null) 323 ut.setDetails(prop.getValue()); 324 325 String filename = null; 326 prop = pl.getProperty("X-NETBEANS-FILENAME"); if (prop != null) 328 filename = prop.getValue(); 329 330 String lineNumber = null; 331 prop = pl.getProperty("X-NETBEANS-LINE"); if (prop != null) 333 lineNumber = prop.getValue(); 334 335 String url = null; 336 prop = pl.getProperty(Property.URL); 337 if (prop != null) 338 url = prop.getValue(); 339 340 String related = null; 341 prop = pl.getProperty(Property.RELATED_TO); 342 if (prop != null) 343 related = prop.getValue(); 344 345 PropertyList deps = pl.getProperties("X-NETBEANS-DEPENDENCY"); for (int i = 0; i < deps.size(); i++) { 347 prop = (Property) deps.get(i); 348 Dep d = new Dep(); 349 d.type = Dependency.END_BEGIN; 350 d.ut = ut; 351 d.dependsOn = prop.getValue(); 352 ParameterList parl = prop.getParameters(); 353 Parameter p = parl.getParameter("X-NETBEANS-TYPE"); 354 if (p != null) { 355 String t = p.getValue(); 356 if (t.equals("BEGIN_BEGIN")) d.type = Dependency.BEGIN_BEGIN; 358 } 359 dependencies.add(d); 360 } 361 362 PropertyList wps = pl.getProperties("X-NETBEANS-WORK-PERIOD"); for (int i = 0; i < wps.size(); i++) { 364 prop = (Property) wps.get(i); 365 ParameterList parl = prop.getParameters(); 366 Parameter p = parl.getParameter("X-NETBEANS-START"); 367 if (p != null) { 368 try { 369 int dur = Integer.parseInt(prop.getValue()); 370 String v = p.getValue(); 371 long start = formatter.parse(v).getTime(); 372 UserTask.WorkPeriod wp = new UserTask.WorkPeriod(start, dur); 373 ut.getWorkPeriods().add(wp); 374 } catch (ParseException e) { 375 UTUtils.LOGGER.log(Level.SEVERE, "", e); } catch (NumberFormatException e) { 377 UTUtils.LOGGER.log(Level.SEVERE, "", e); } 379 } 380 } 381 382 if (pl.getProperty("X-NETBEANS-VALUES-COMPUTED") == null && 383 pl.getProperty("X-NETBEANS-PROGRESS-COMPUTED") != null && 385 pl.getProperty("X-NETBEANS-PROGRESS-COMPUTED"). getValue().equals("yes") && pl.getProperty("X-NETBEANS-EFFORT-COMPUTED") != null && 389 pl.getProperty("X-NETBEANS-EFFORT-COMPUTED"). getValue().equals("yes") && pl.getProperty("X-NETBEANS-SPENT-TIME-COMPUTED") != null && 393 pl.getProperty("X-NETBEANS-SPENT-TIME-COMPUTED"). getValue().equals("yes") ) { 396 ut.setValuesComputed(true); 397 } else { 398 prop = pl.getProperty("X-NETBEANS-VALUES-COMPUTED"); if (prop != null) 400 ut.setValuesComputed(prop.getValue().equals("yes")); else 402 ut.setValuesComputed(false); 403 } 404 434 prop = pl.getProperty("X-NETBEANS-DUETIME"); if (prop != null) { 436 java.util.Date d = null; 437 try { 438 d = new java.util.Date (Long.parseLong(prop.getValue())); 439 ut.setDueDate(d); 440 } catch (NumberFormatException e) { 441 UTUtils.LOGGER.log(Level.SEVERE, "", e); } 443 } 444 445 prop = pl.getProperty(Property.DUE); 446 if (prop != null) { 447 ut.setDueDate(((DateProperty) prop).getDate()); 448 } 449 450 prop = pl.getProperty("X-NETBEANS-DUE-SIGNALED"); if (prop != null) 452 ut.setDueAlarmSent(true); 453 454 485 prop = pl.getProperty(Property.COMPLETED); 486 if (prop != null) 487 ut.setCompletedDate(((DateProperty) prop).getDate().getTime()); 488 489 int lineno = 1; 490 if (lineNumber != null) { 491 try { 492 lineno = Integer.parseInt(lineNumber); 493 } catch (NumberFormatException e) { 494 } 496 } 497 498 if (lineno < 1) 499 lineno = 1; 500 501 FileObject fo = null; 502 if (url != null) { 503 try { 504 fo = URLMapper.findFileObject(new URL (url)); 505 } catch (MalformedURLException e) { 506 } 508 } 509 510 if (fo == null && filename != null) { 511 fo = UTUtils.getFileObjectForFile(filename); 512 } 513 514 if (fo != null) { 515 Line line = UTUtils.getLineByFile(fo, lineno - 1); 516 if (line == null) 517 line = UTUtils.getLineByFile(fo, 0); 518 519 if (line != null) { 520 ut.setLine(line); 521 } 522 } else if (url != null) { 523 try { 524 ut.setUrl(new URL (url)); 525 ut.setLineNumber(lineno - 1); 526 } catch (MalformedURLException e) { 527 } 529 } 530 531 535 UserTask alreadyExists = utl.findItem( 536 utl.getSubtasks().iterator(), ut.getUID()); 537 UserTask parent = null; 538 if (alreadyExists != null) { 539 parent = alreadyExists.getParent(); 541 if (parent != null) { 542 parent.getSubtasks().remove(alreadyExists); 543 } else { 544 utl.getSubtasks().remove(alreadyExists); 545 } 546 547 Iterator li = alreadyExists.getSubtasks().iterator(); 548 while (li.hasNext()) { 549 UserTask c = (UserTask)li.next(); 550 alreadyExists.getSubtasks().remove(c); 551 ut.getSubtasks().add(c); 552 } 553 } else if (related != null) { 554 parent = utl.findItem(utl.getSubtasks().iterator(), related); 556 } 557 558 prop = pl.getProperty(Property.LAST_MODIFIED); 559 if (prop != null) 560 ut.setLastEditedDate(((DateProperty) prop).getDate().getTime()); 561 562 if (parent != null) 563 parent.getSubtasks().add(ut); 564 else 565 utl.getSubtasks().add(ut); 566 } 567 568 public String getName() { 569 return NbBundle.getMessage(ICalImportFormat.class, "iCalImp"); } 571 572 public org.openide.WizardDescriptor getWizard() { 573 OpenFilePanel chooseFilePanel = new OpenFilePanel(); 574 SimpleWizardPanel chooseFileWP = new SimpleWizardPanel(chooseFilePanel); 575 chooseFilePanel.setWizardPanel(chooseFileWP); 576 chooseFilePanel.getFileChooser().addChoosableFileFilter( 577 new ExtensionFileFilter( 578 NbBundle.getMessage(XmlExportFormat.class, 579 "IcsFilter"), new String [] {".ics"})); chooseFilePanel.setFile(new File ( 582 FileSystemView.getFileSystemView(). 583 getDefaultDirectory(), "tasklist.ics")); 585 WizardDescriptor.Iterator iterator = 587 new WizardDescriptor.ArrayIterator(new WizardDescriptor.Panel[] { 588 chooseFileWP 589 }); 590 WizardDescriptor d = new WizardDescriptor(iterator); 591 d.putProperty("WizardPanel_contentData", new String [] { 593 NbBundle.getMessage( 594 ICalImportFormat.class, "ChooseSource"), } 596 ); 597 598 String title; 599 title = NbBundle.getMessage(ICalImportFormat.class, "ImportICAL"); d.setTitle(title); d.putProperty(CHOOSE_FILE_PANEL_PROP, chooseFilePanel); 602 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; 607 } 608 } 609 | Popular Tags |