package net.java.nboglpack.joglproject; import java.awt.Component; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.MessageFormat; import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.NoSuchElementException; import java.util.Properties; import java.util.Scanner; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.swing.JComponent; import javax.swing.SwingUtilities; import javax.swing.event.ChangeListener; import org.apache.tools.ant.module.api.support.ActionUtils; import org.netbeans.api.project.ProjectManager; import org.netbeans.spi.project.ui.support.ProjectChooser; import org.netbeans.spi.project.ui.templates.support.Templates; import org.openide.WizardDescriptor; import org.openide.cookies.OpenCookie; import org.openide.execution.ExecutorTask; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.modules.InstalledFileLocator; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; /** * Iterates through the new-JOGL-project wizzard. * @author Mathias Henze * @author Michael Bien */ public class ProjectWizardIterator implements WizardDescriptor.InstantiatingIterator<WizardDescriptor> { private static final long serialVersionUID = 1L; private transient String createLabel="LBL_CreateProjectStep"; private transient int index; private transient WizardDescriptor.Panel<WizardDescriptor>[] panels; private transient WizardDescriptor wiz; public ProjectWizardIterator() {} public static ProjectWizardIterator createIterator() { return new ProjectWizardIterator(); } @SuppressWarnings("unchecked") private WizardDescriptor.Panel<WizardDescriptor>[] createPanels() { return new WizardDescriptor.Panel[] { new ProjectWizardPanel(), }; } private String[] createSteps() { return new String[] { NbBundle.getMessage(ProjectWizardIterator.class, createLabel) }; } public Set<FileObject> instantiate() throws IOException { FileObject template = Templates.getTemplate(wiz); String demo=(String)template.getAttribute("demo"); createLabel="LBL_Create_"+demo; Set<FileObject> resultSet = new LinkedHashSet<FileObject>(); File dirF = FileUtil.normalizeFile((File) wiz.getProperty("projdir")); dirF.mkdirs(); FileObject dir = FileUtil.toFileObject(dirF); unZipFile(template.getInputStream(), dir); callInitScript( dirF, (String)wiz.getProperty("name"), (String)wiz.getProperty("projpackage"), (String)wiz.getProperty("projclass"), demo, (String)template.getAttribute("archive"), (String)template.getAttribute("srcPath"), (String)template.getAttribute("extraFiles"), (String)wiz.getProperty("platform"), (String)template.getAttribute("includes"), (String)template.getAttribute("excludes") ); // Always open top dir as a project: resultSet.add(dir); // Look for nested projects to open as well: Enumeration e = dir.getFolders(true); while (e.hasMoreElements()) { FileObject subfolder = (FileObject) e.nextElement(); if (ProjectManager.getDefault().isProject(subfolder)) { resultSet.add(subfolder); } } File parent = dirF.getParentFile(); if (parent != null && parent.exists()) { ProjectChooser.setProjectsFolder(parent); } return resultSet; } public void initialize(WizardDescriptor wiz) { this.wiz = wiz; FileObject template = Templates.getTemplate(wiz); String projectPackage= (String) template.getAttribute("projectPackage"); if(projectPackage != null && projectPackage.trim().length() != 0) this.wiz.putProperty("projpackage",projectPackage); this.wiz.putProperty("name",template.getAttribute("projectName")); index = 0; panels = createPanels(); // Make sure list of steps is accurate. String[] steps = createSteps(); for (int i = 0; i < panels.length; i++) { Component c = panels[i].getComponent(); if (steps[i] == null) { // Default step name to component name of panel. // Mainly useful for getting the name of the target // chooser to appear in the list of steps. steps[i] = c.getName(); } if (c instanceof JComponent) { // assume Swing components JComponent jc = (JComponent) c; // Step #. jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i)); // Step name (actually the whole list for reference). jc.putClientProperty("WizardPanel_contentData", steps); } } } public void uninitialize(WizardDescriptor wiz) { this.wiz.putProperty("projdir", null); this.wiz.putProperty("name", null); this.wiz.putProperty("projpackage", null); this.wiz.putProperty("projclass", null); this.wiz = null; panels = null; } public String name() { return MessageFormat.format("{0} of {1}", new Object[]{new Integer(index + 1), new Integer(panels.length)}); } public boolean hasNext() { return index < panels.length - 1; } public boolean hasPrevious() { return index > 0; } public void nextPanel() { if (!hasNext()) { throw new NoSuchElementException(); } index++; } public void previousPanel() { if (!hasPrevious()) { throw new NoSuchElementException(); } index--; } public WizardDescriptor.Panel<WizardDescriptor> current() { return panels[index]; } // If nothing unusual changes in the middle of the wizard, simply: public final void addChangeListener(ChangeListener l) { } public final void removeChangeListener(ChangeListener l) { } private static void unZipFile(InputStream source, FileObject projectRoot) throws IOException { try { ZipInputStream str = new ZipInputStream(source); ZipEntry entry; while ((entry = str.getNextEntry()) != null) { if (entry.isDirectory()) { FileUtil.createFolder(projectRoot, entry.getName()); } else { FileObject fo = FileUtil.createData(projectRoot, entry.getName()); FileLock lock = fo.lock(); try { OutputStream out = fo.getOutputStream(lock); try { FileUtil.copy(str, out); } finally { out.close(); } } finally { lock.releaseLock(); } } } } finally { source.close(); } } private void callInitScript(File dir, String projectName, String packageName, String mainClass, String demo, String archive, String srcPath, String extraFiles, String platform, String includes, String excludes) { if(includes==null) includes=""; if(excludes==null) excludes=""; if(srcPath==null) srcPath=""; srcPath = srcPath.trim(); excludes = excludes.trim(); includes = includes.trim(); if(srcPath.length()!=0 && !srcPath.endsWith("/")) { srcPath+="/"; } InstalledFileLocator locator = InstalledFileLocator.getDefault(); File archiveFile = locator.locate("jogl-project/"+archive,null,false); Properties props = new Properties(); props.setProperty("project.root", dir.getAbsolutePath()); props.setProperty("project.name", projectName); props.setProperty("project.packageName", packageName); props.setProperty("project.packagePath", packageName.replace('.','/')); props.setProperty("project.mainClass", mainClass); String demoPackage = demo.replaceAll("^(.*?)\\.[^\\.]+$","$1"); String demoPath = demoPackage.replace('.','/'); String demoClass = demo.replaceAll("^.*?\\.([^\\.]+)$","$1"); props.setProperty("template.demoPath", demoPath); props.setProperty("template.demoPackage", demoPackage); props.setProperty("template.demoClass", demoClass); props.setProperty("template.demoPath.regex", demoPath.replaceAll("([\\.\\/])","\\\\$1")); props.setProperty("template.demoPackage.regex", demoPackage.replaceAll("([\\.\\/])","\\\\$1")); props.setProperty("template.demoClass.regex", demoClass.replaceAll("([\\.\\/])","\\\\$1")); props.setProperty("template.archive", archiveFile.getAbsolutePath()); props.setProperty("template.srcPath", srcPath); props.setProperty("template.excludes", ""); props.setProperty("natives.platform", platform); // path to jogl distributions props.setProperty("jogl.runtime.distribution", locator.locate("jogl-runtime2/jogl-2.0-webstart.zip", null, false).getPath()); props.setProperty("nativewindow.runtime.distribution", locator.locate("jogl-runtime2/nativewindow-2.0-webstart.zip", null, false).getPath()); props.setProperty("newt.runtime.distribution", locator.locate("jogl-runtime2/newt-2.0-webstart.zip", null, false).getPath()); props.setProperty("gluegen.runtime.distribution", locator.locate("gluegen-runtime2/gluegen-rt-2.0-webstart.zip", null, false).getPath()); try{ //sources props.setProperty("jogl.runtime.src", locator.locate("jogl-runtime2/jogl-2.0-src.zip", null, false).getPath()); props.setProperty("gluegen.runtime.src", locator.locate("gluegen-runtime2/gluegen-rt-2.0-src.zip", null, false).getPath()); props.setProperty("newt.runtime.src", locator.locate("jogl-runtime2/newt-2.0-src.zip", null, false).getPath()); props.setProperty("nativewindow.runtime.src", locator.locate("jogl-runtime2/nativewindow-2.0-src.zip", null, false).getPath()); //docs props.setProperty("jogl.runtime.doc", locator.locate("jogl-runtime2/jogl-2.0-docs.zip", null, false).getPath()); }catch(Throwable t) { Logger.getLogger(this.getClass().getName()).log( Level.INFO, "Can not deploy documentation. API support module installed?", t); } if (includes != null && includes.length() != 0) { String mergedIncludes = null; Scanner scanner = new Scanner(includes).useDelimiter(","); while (scanner.hasNext()) { String token = scanner.next(); if (mergedIncludes == null) { mergedIncludes = srcPath + token; } else { mergedIncludes += "," + srcPath + token; } } props.setProperty("template.includes", mergedIncludes); } if (excludes != null && excludes.length() != 0) { String mergedExcludes = null; Scanner scanner = new Scanner(excludes).useDelimiter(","); while (scanner.hasNext()) { String token = scanner.next(); if (mergedExcludes == null) { mergedExcludes = srcPath + token; } else { mergedExcludes += "," + srcPath + token; } } props.setProperty("template.excludes", mergedExcludes); } try { File scriptFile=InstalledFileLocator.getDefault().locate("jogl-project/initJoglProject.xml",null,false); FileObject script= FileUtil.toFileObject(scriptFile); ExecutorTask task= ActionUtils.runTarget(script,new String[]{"initProject"},props); task.waitFinished(); // open main file in editor final File mainFile = new File( dir.getAbsolutePath()+File.separator +"src"+File.separator +packageName.replace('.',File.separatorChar)+File.separator +mainClass+".java" ); // add a delay and try to open the main file later Runnable opener = new Runnable() { @Override public void run() { try{ final DataObject mainDAO = DataObject.find(FileUtil.toFileObject(mainFile)); // and back to the EDT SwingUtilities.invokeLater(new Runnable() { public void run() { try{ mainDAO.getLookup().lookup(OpenCookie.class).open(); }catch(Exception ex) { Logger.getLogger(this.getClass().getName()).log( Level.INFO, "could not open main file in editor", ex); } } }); }catch(Exception ex) { Logger.getLogger(this.getClass().getName()).log( Level.INFO, "could not find/open main file in editor", ex); } } }; RequestProcessor rp = RequestProcessor.getDefault(); rp.post(opener, 3000); } catch (Exception ex) { Logger.getLogger(this.getClass().getName()).log( Level.SEVERE, "error while deploying project", ex); } } }