Posts Tagged ‘build’

Custom project file structure in NetBeans - new menu item in projects

Monday, May 12th, 2008

In a previous post, I’ve told that I want to use NetBeans and share projects with developers that still use Eclipse. In another post, I added a custom folder to the project view.

Now, I will add a custom menu item to run an ant task outside NB’s build scripts:

  1. Assuming you have a NB module project ready, you just need to add a new entry in your layer.xml:
    <folder name="Projects">
      <folder name="Actions">
        <file name="org-mycompany-MyMenuAction.instance"/>
      </folder>
    </folder>
  2. Create a new class with the same name (org.mycompany.MyMenuAction):
    public final class TransitMenuAction
      extends AbstractAction
      implements Presenter.Popup, ContextAwareAction {
    
      public final static String DISPLAY_NAME =
        NbBundle.getMessage(TransitMenuAction.class,
          "CTL_TransitMenuAction");
    
      private Lookup context;
    
      public TransitMenuAction() {
        this(null);
      }
      public TransitMenuAction(Lookup context) {
        super(DISPLAY_NAME);
        this.context = context;
      }
    
      public void actionPerformed(ActionEvent e) {
        // I'm a menu container... I do nothing
      }
    
      public Action createContextAwareInstance(
        Lookup context) {
        return new MyMenuAction(context);
      }
      public JMenuItem getPopupPresenter() {
        return new PopupPresenter();
      }
    
      /** Dynamic menu factory */
      class PopupPresenter extends JMenuItem
        implements DynamicMenuContent {
    
        public JComponent[] getMenuPresenters() {
          Project proj = context.lookup(Project.class);
          // MyUtils comes from last post
          if (!MyUtils.isMyProject(proj)) {
            // hides this menu
            return new JComponent[0];
          }
    
          JMenu mnu = new JMenu(DISPLAY_NAME);
          mnu.add(new PackageAction(context));
          return new JComponent[] { mnu };
        }
        public JComponent[] synchMenuPresenters(
          JComponent[] items) {
          return items;
        }
      }
    }
  3. And, the PackageAction is:
    public class PackageAction extends AbstractAction {
      private Lookup context;
      public PackageAction(Lookup context) {
        super(NbBundle.getMessage(PackageAction.class,
          "CTL_PackageAction"));
        this.context = context;
      }
    
      /* This action will copy a file and run an Ant task */
      public void actionPerformed(ActionEvent e) {
        try {
          /* Both the file and the build scripts are under
           * the "ant" folder in project directory
           */
          Project proj = context.lookup(Project.class);
          FileObject antFolder = proj.getProjectDirectory().
            getFileObject("ant");
    
          // Read the original file
          FileObject def = antFolder.
            getFileObject("compile-default.properties");
          Properties prop = new Properties();
          prop.load(def.getInputStream());
    
          // Change a little bit
          // TODO: Add this to a property window
          prop.setProperty("compile.lib.ext",
            "C:\\etc\\apache-tomcat-6.0.14\\lib");
    
          // Write to the copy file
          FileObject cpy = antFolder
            .getFileObject("compile.properties");
          if (cpy == null) {
            cpy = antFolder.createData("compile.properties");
          }
          FileLock lock = cpy.lock();
          try {
            prop.store(cpy.getOutputStream(lock),
              "any cool comment");
          } finally {
            lock.releaseLock();
          }
    
          // Now, we will run Ant - grab the script...
          FileObject buildXML = antFolder
            .getFileObject("build.xml");
    
          // ... and run the "package" target
          ActionUtils.runTarget(buildXML,
             new String[]{ "package" }, null);
        } catch (IOException ex) {
          Exceptions.printStackTrace(ex);
        } catch (IllegalArgumentException ex) {
          Exceptions.printStackTrace(ex);
        }
      }
    }
  4. Last, but not least, the project dependencies:
    1. Ant (ActionUtils)
    2. Filesystem API (FileObject and FileLock);
    3. Project API (Project);
    4. UI Utilities API (DynamicMenuContent); and
    5. Utilities API (Lookup)

And, your new project menu item (that calls an Ant task) is ready.

Custom project file structure in NetBeans

Monday, May 12th, 2008

In my job, they officially use Eclipse Europa to develop. I really dislike Eclipse - it is a matter of taste. Because of this, I’m using NetBeans ability to share projects (like in this demo) - and it works like a charm.

But, since even rose has its thorn, they have some custom tasks here:

  1. Inside every project, there’s a “config” folder with some files that must be copied to a “/var/xxx” folder before running the application;
  2. A custom ant build script to create a ZIP file that will go to test and production environments; and
  3. The file from step 2 must be transfered via SFTP to specific servers, on a folder named like “/var/deploy/xxx”.

These are manually-repeated tasks that must be done for every project. Eclipse users (here) must do it step-by-step. NetBeans users will use a (custom) brand-new module that I developed to do these tasks.

Just to enumerate, we need to solve these problems:

  1. The “config” folder must be visible in “Projects” tab (it is under “Files” tab, but it is ugly);
  2. An ant task in a custom build script must be called whenever I want;
  3. The “config” folder must be copied to “/var/xxx” when the project is compiled;
  4. An ZIP file must be sent via SFTP to a “/var/deploy/xxx” folder;
  5. I don’t want to hardcode the “xxx” - what about a new tab on project properties?

OK. We have a lot of things to cover here. But, they are very simple. Since it could become a large post, I’ll cover them in other posts (that will be have a pingback here, on comments section).