1 19 20 package org.netbeans.modules.apisupport.project.ui.wizard.action; 21 22 import java.net.URL ; 23 import java.util.Arrays ; 24 import java.util.Collections ; 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.Map ; 29 import java.util.Set ; 30 import java.util.TreeSet ; 31 import org.netbeans.modules.apisupport.project.CreatedModifiedFiles; 32 import org.netbeans.modules.apisupport.project.ui.wizard.BasicWizardIterator; 33 import org.openide.WizardDescriptor; 34 import org.openide.filesystems.FileObject; 35 36 39 final class DataModel extends BasicWizardIterator.BasicDataModel { 40 41 static final String [] PREDEFINED_COOKIE_CLASSES; 42 43 private static final String [] HARDCODED_IMPORTS = new String [] { 44 "org.openide.nodes.Node", "org.openide.util.HelpCtx", "org.openide.util.NbBundle", "org.openide.util.actions.CookieAction" }; 49 50 51 private static final Map <String ,String > CLASS_TO_CNB; 52 53 static { 54 Map map = new HashMap (5); 55 map.put("org.openide.loaders.DataObject", "org.openide.loaders"); map.put("org.openide.cookies.EditCookie", "org.openide.nodes"); map.put("org.openide.cookies.OpenCookie", "org.openide.nodes"); map.put("org.netbeans.api.project.Project", "org.netbeans.modules.projectapi"); map.put("org.openide.cookies.EditorCookie", "org.openide.text"); CLASS_TO_CNB = Collections.unmodifiableMap(map); 61 PREDEFINED_COOKIE_CLASSES = new String [5]; 62 DataModel.CLASS_TO_CNB.keySet().toArray(PREDEFINED_COOKIE_CLASSES); 63 } 64 65 private static final String NEW_LINE = System.getProperty("line.separator"); 67 68 private static final String INDENT = " "; 70 private static final String INDENT_2X = INDENT + INDENT; 72 private CreatedModifiedFiles cmf; 73 74 private boolean alwaysEnabled; 76 private String [] cookieClasses; 77 private boolean multiSelection; 78 79 private String category; 81 82 private boolean globalMenuItemEnabled; 84 private String gmiParentMenuPath; 85 private Position gmiPosition; 86 private boolean gmiSeparatorAfter; 87 private boolean gmiSeparatorBefore; 88 89 private boolean toolbarEnabled; 91 private String toolbar; 92 private Position toolbarPosition; 93 94 private boolean kbShortcutEnabled; 96 private final Set keyStrokes = new HashSet (); 97 98 private boolean ftContextEnabled; 100 private String ftContextType; 101 private Position ftContextPosition; 102 private boolean ftContextSeparatorAfter; 103 private boolean ftContextSeparatorBefore; 104 105 private boolean edContextEnabled; 107 private String edContextType; 108 private Position edContextPosition; 109 private boolean edContextSeparatorAfter; 110 private boolean edContextSeparatorBefore; 111 112 private String className; 114 private String displayName; 115 private String origIconPath; 116 private String largeIconPath; 117 118 DataModel(WizardDescriptor wiz) { 119 super(wiz); 120 } 121 122 private void regenerate() { 123 String dashedPkgName = getPackageName().replace('.', '-'); 124 String dashedFqClassName = dashedPkgName + '-' + className; 125 String shadow = dashedFqClassName + ".shadow"; 127 cmf = new CreatedModifiedFiles(getProject()); 128 129 String actionPath = getDefaultPackagePath(className + ".java", false); URL template = DataModel.class.getResource(alwaysEnabled 132 ? "callableSystemAction.javx" : "cookieAction.javx"); String actionNameKey = "CTL_" + className; Map replaceTokens = new HashMap (); 135 replaceTokens.put("@@CLASS_NAME@@", className); replaceTokens.put("@@PACKAGE_NAME@@", getPackageName()); replaceTokens.put("@@DISPLAY_NAME_KEY@@", actionNameKey); replaceTokens.put("@@MODE@@", getSelectionMode()); Set imports = new TreeSet (Arrays.asList(HARDCODED_IMPORTS)); 140 Set addedFQNCs = new TreeSet (); 141 if (!alwaysEnabled) { 142 StringBuffer cookieSB = new StringBuffer (); 143 for (int i = 0; i < cookieClasses.length; i++) { 144 if (CLASS_TO_CNB.containsKey(cookieClasses[i])) { 146 addedFQNCs.add(cookieClasses[i]); 147 } 148 cookieSB.append(INDENT_2X + INDENT + parseClassName(cookieClasses[i]) + ".class"); if (i != cookieClasses.length - 1) { 151 cookieSB.append(',' + NEW_LINE); 152 } 153 } 154 replaceTokens.put("@@COOKIE_CLASSES_BLOCK@@", cookieSB.toString()); String impl; 156 if (cookieClasses.length == 1) { 157 String cName = parseClassName(cookieClasses[0]); 158 String cNameVar = Character.toLowerCase(cName.charAt(0)) + cName.substring(1); 159 impl = cName + ' ' + cNameVar + " = (" + cName + ") activatedNodes[0].getLookup().lookup(" + cName + ".class);\n" + INDENT_2X + "// TODO use " + cNameVar; } else { 162 impl = "// TODO implement action body"; } 164 replaceTokens.put("@@PERFORM_ACTION_CODE@@", impl); } 166 imports.addAll(addedFQNCs); 168 StringBuffer importsBuffer = new StringBuffer (); 169 for (Iterator it = imports.iterator(); it.hasNext();) { 170 importsBuffer.append("import " + it.next() + ';' + NEW_LINE); } 172 replaceTokens.put("@@IMPORTS@@", importsBuffer.toString()); cmf.add(cmf.createFileWithSubstitutions(actionPath, template, replaceTokens)); 174 175 cmf.add(cmf.bundleKey(getDefaultPackagePath("Bundle.properties", true), actionNameKey, displayName)); 178 if (origIconPath != null) { 180 String relativeIconPath = addCreateIconOperation(cmf, origIconPath); 181 replaceTokens.put("@@ICON_RESOURCE_METHOD@@", DataModel.generateIconResourceMethod(relativeIconPath)); replaceTokens.put("@@INITIALIZE_METHOD@@", ""); } else { 184 replaceTokens.put("@@ICON_RESOURCE_METHOD@@", ""); replaceTokens.put("@@INITIALIZE_METHOD@@", DataModel.generateNoIconInitializeMethod()); } 187 188 if (isToolbarEnabled() && largeIconPath != null) { 189 addCreateIconOperation(cmf, largeIconPath); 190 } 191 192 String instanceFullPath = category + "/" + dashedFqClassName + ".instance"; cmf.add(cmf.createLayerEntry(instanceFullPath, null, null, null, null)); 196 197 cmf.add(cmf.addModuleDependency("org.openide.util")); if (!alwaysEnabled) { 200 cmf.add(cmf.addModuleDependency("org.openide.nodes")); for (Iterator it = addedFQNCs.iterator(); it.hasNext(); ) { 202 cmf.add(cmf.addModuleDependency((String ) CLASS_TO_CNB.get(it.next()))); 203 } 204 } 205 206 if (globalMenuItemEnabled) { 208 generateShadowWithOrderAndSeparator(gmiParentMenuPath, shadow, 209 dashedPkgName, instanceFullPath, gmiSeparatorBefore, 210 gmiSeparatorAfter, gmiPosition); 211 } 212 213 if (toolbarEnabled) { 215 generateOrder(toolbar, toolbarPosition.getBefore(), shadow); 216 generateShadow(toolbar + "/" + shadow, instanceFullPath); generateOrder(toolbar, shadow, toolbarPosition.getAfter()); 218 } 219 220 if (kbShortcutEnabled) { 222 String parentPath = "Shortcuts"; for (Iterator it = keyStrokes.iterator(); it.hasNext();) { 224 String keyStroke = (String ) it.next(); 225 generateShadow(parentPath + "/" + keyStroke + ".shadow", instanceFullPath); } 227 } 228 229 if (ftContextEnabled) { 231 generateShadowWithOrderAndSeparator(ftContextType, shadow, 232 dashedPkgName, instanceFullPath, ftContextSeparatorBefore, 233 ftContextSeparatorAfter, ftContextPosition); 234 } 235 236 if (edContextEnabled) { 238 generateShadowWithOrderAndSeparator(edContextType, shadow, 239 dashedPkgName, instanceFullPath, edContextSeparatorBefore, 240 edContextSeparatorAfter, edContextPosition); 241 } 242 } 243 244 private void generateShadowWithOrderAndSeparator( 245 final String parentPath, 246 final String shadow, 247 final String dashedPkgName, 248 final String instanceFullPath, 249 final boolean separatorBefore, 250 final boolean separatorAfter, 251 final Position position) { 252 if (separatorBefore) { 253 String sepName = dashedPkgName + "-separatorBefore.instance"; generateSeparator(parentPath, sepName); 255 generateOrder(parentPath, position.getBefore(), sepName); 256 generateOrder(parentPath, sepName, shadow); 257 } else { 258 generateOrder(parentPath, position.getBefore(), shadow); 259 } 260 generateShadow(parentPath + "/" + shadow, instanceFullPath); if (separatorAfter) { 262 String sepName = dashedPkgName + "-separatorAfter.instance"; generateSeparator(parentPath, sepName); 264 generateOrder(parentPath, shadow, sepName); 265 generateOrder(parentPath, sepName, position.getAfter()); 266 } else { 267 generateOrder(parentPath, shadow, position.getAfter()); 268 } 269 } 270 271 276 private void generateOrder(String layerPath, String before, String after) { 277 if (before != null && after != null) { 278 cmf.add(cmf.orderLayerEntry(layerPath, before, after)); 279 } 280 } 281 282 283 boolean classExists() { 284 FileObject classFO = getProject().getProjectDirectory().getFileObject( 285 getDefaultPackagePath(className + ".java", false)); return classFO != null; 287 } 288 289 private void generateShadow(final String itemPath, final String origInstance) { 290 cmf.add(cmf.createLayerEntry(itemPath, null, null, null, null)); 291 cmf.add(cmf.createLayerAttribute(itemPath, "originalFile", origInstance)); } 293 294 CreatedModifiedFiles getCreatedModifiedFiles() { 295 if (cmf == null) { 296 regenerate(); 297 } 298 return cmf; 299 } 300 301 private void reset() { 302 cmf = null; 303 } 304 305 void setAlwaysEnabled(boolean alwaysEnabled) { 306 this.alwaysEnabled = alwaysEnabled; 307 } 308 309 boolean isAlwaysEnabled() { 310 return alwaysEnabled; 311 } 312 313 void setCookieClasses(String [] cookieClasses) { 314 this.cookieClasses = cookieClasses; 315 } 316 317 void setMultiSelection(boolean multiSelection) { 318 this.multiSelection = multiSelection; 319 } 320 321 private String getSelectionMode() { 322 return multiSelection ? "MODE_ALL" : "MODE_EXACTLY_ONE"; } 324 325 void setCategory(String category) { 326 this.category = category; 327 } 328 329 void setClassName(String className) { 330 reset(); 331 this.className = className; 332 } 333 334 public String getClassName() { 335 return className; 336 } 337 338 void setDisplayName(String display) { 339 this.displayName = display; 340 } 341 342 public String getDisplayName() { 343 return displayName; 344 } 345 346 void setIconPath(String origIconPath) { 347 reset(); 348 this.origIconPath = origIconPath; 349 } 350 351 public String getIconPath() { 352 return origIconPath; 353 } 354 355 public void setPackageName(String pkg) { 356 super.setPackageName(pkg); 357 reset(); 358 } 359 360 void setGlobalMenuItemEnabled(boolean globalMenuItemEnabled) { 361 this.globalMenuItemEnabled = globalMenuItemEnabled; 362 } 363 364 void setGMIParentMenu(String gmiParentMenuPath) { 365 this.gmiParentMenuPath = gmiParentMenuPath; 366 } 367 368 void setGMISeparatorAfter(boolean gmiSeparatorAfter) { 369 this.gmiSeparatorAfter = gmiSeparatorAfter; 370 } 371 372 void setGMISeparatorBefore(boolean gmiSeparatorBefore) { 373 this.gmiSeparatorBefore = gmiSeparatorBefore; 374 } 375 376 void setGMIPosition(Position position) { 377 this.gmiPosition = position; 378 } 379 380 void setToolbarEnabled(boolean toolbarEnabled) { 381 this.toolbarEnabled = toolbarEnabled; 382 } 383 384 boolean isToolbarEnabled() { 385 return toolbarEnabled; 386 } 387 388 void setToolbar(String toolbar) { 389 this.toolbar = toolbar; 390 } 391 392 void setToolbarPosition(Position position) { 393 this.toolbarPosition = position; 394 } 395 396 void setKeyboardShortcutEnabled(boolean kbShortcutEnabled) { 397 this.kbShortcutEnabled = kbShortcutEnabled; 398 } 399 400 void setKeyStroke(String keyStroke) { 401 keyStrokes.add(keyStroke); 402 } 403 404 void setFileTypeContextEnabled(boolean contextEnabled) { 405 this.ftContextEnabled = contextEnabled; 406 } 407 408 void setFTContextType(String contextType) { 409 this.ftContextType = contextType; 410 } 411 412 void setFTContextPosition(Position position) { 413 this.ftContextPosition = position; 414 } 415 416 void setFTContextSeparatorAfter(boolean separator) { 417 this.ftContextSeparatorAfter = separator; 418 } 419 420 void setFTContextSeparatorBefore(boolean separator) { 421 this.ftContextSeparatorBefore = separator; 422 } 423 424 void setEditorContextEnabled(boolean contextEnabled) { 425 this.edContextEnabled = contextEnabled; 426 } 427 428 void setEdContextType(String contextType) { 429 this.edContextType = contextType; 430 } 431 432 void setEdContextPosition(Position position) { 433 this.edContextPosition = position; 434 } 435 436 void setEdContextSeparatorAfter(boolean separator) { 437 this.edContextSeparatorAfter = separator; 438 } 439 440 void setEdContextSeparatorBefore(boolean separator) { 441 this.edContextSeparatorBefore = separator; 442 } 443 444 static final class Position { 445 446 private String before; 447 private String after; 448 private String beforeName; 449 private String afterName; 450 451 Position(String before, String after) { 452 this(before, after, null, null); 453 } 454 455 Position(String before, String after, String beforeName, String afterName) { 456 this.before = before; 457 this.after = after; 458 this.beforeName = beforeName; 459 this.afterName = afterName; 460 } 461 462 String getBefore() { 463 return before; 464 } 465 466 String getAfter() { 467 return after; 468 } 469 470 String getBeforeName() { 471 return beforeName; 472 } 473 474 String getAfterName() { 475 return afterName; 476 } 477 } 478 479 private void generateSeparator(final String parentPath, final String sepName) { 480 String sepPath = parentPath + "/" + sepName; cmf.add(cmf.createLayerEntry(sepPath, 482 null, null, null, null)); 483 cmf.add(cmf.createLayerAttribute(sepPath, "instanceClass", "javax.swing.JSeparator")); } 486 487 491 static String parseClassName(final String name) { 492 int lastDot = name.lastIndexOf('.'); 493 return lastDot == -1 ? name : name.substring(lastDot + 1); 494 } 495 496 private static String generateIconResourceMethod(final String relativeIconPath) { 497 return NEW_LINE + 498 INDENT + "protected String iconResource() {" + NEW_LINE + INDENT_2X + "return \"" + relativeIconPath + "\";" + NEW_LINE + INDENT + "}"; } 502 503 private static String generateNoIconInitializeMethod() { 504 return "protected void initialize() {" + NEW_LINE + INDENT_2X + "super.initialize();" + NEW_LINE + INDENT_2X + "// see org.openide.util.actions.SystemAction.iconResource() javadoc for more details" + NEW_LINE + INDENT_2X + "putValue(\"noIconInMenu\", Boolean.TRUE);" + NEW_LINE + INDENT + "}" + NEW_LINE; } 510 511 public void setLargeIconPath(String largeIconPath) { 512 this.largeIconPath = largeIconPath; 513 } 514 515 } 516 517 | Popular Tags |