| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.web.wizards; |
| |
| import java.awt.Component; |
| import java.io.IOException; |
| import java.util.Collections; |
| import java.util.NoSuchElementException; |
| import java.util.Set; |
| import java.text.MessageFormat; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.swing.JComponent; |
| import javax.swing.event.ChangeListener; |
| import org.netbeans.api.j2ee.core.Profile; |
| import org.netbeans.api.java.source.JavaSource; |
| import org.netbeans.modules.web.core.Util; |
| import org.openide.filesystems.FileObject; |
| import org.openide.WizardDescriptor; |
| import org.openide.cookies.SaveCookie; |
| import org.openide.loaders.*; |
| import org.openide.util.NbBundle; |
| import org.openide.NotifyDescriptor; |
| import org.openide.DialogDisplayer; |
| import org.netbeans.spi.project.ui.templates.support.Templates; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.Sources; |
| import org.netbeans.api.project.SourceGroup; |
| import org.netbeans.modules.j2ee.core.api.support.classpath.ContainerClassPathModifier; |
| import org.netbeans.modules.web.api.webmodule.WebModule; |
| import org.netbeans.modules.web.api.webmodule.WebProjectConstants; |
| import org.netbeans.spi.java.project.support.ui.templates.JavaTemplates; |
| import org.netbeans.modules.web.taglib.TLDDataObject; |
| import org.netbeans.modules.web.taglib.TaglibCatalog; |
| import org.netbeans.modules.web.taglib.model.Taglib; |
| import org.netbeans.modules.web.taglib.model.TagType; |
| import org.netbeans.modules.web.taglib.model.TldAttributeType; |
| |
| /** A template wizard iterator (sequence of panels). |
| * Used to fill in the second and subsequent panels in the New wizard. |
| * Associate this to a template inside a layer using the |
| * Sequence of Panels extra property. |
| * Create one or more panels from template as needed too. |
| * |
| * @author mk115033 |
| */ |
| public class TagHandlerIterator implements TemplateWizard.AsynchronousInstantiatingIterator { |
| private static final Logger LOG = Logger.getLogger(TagHandlerIterator.class.getName()); |
| private WizardDescriptor.Panel packageChooserPanel,tagHandlerSelectionPanel,tagInfoPanel; |
| |
| // You should define what panels you want to use here: |
| protected WizardDescriptor.Panel[] createPanels (Project project,TemplateWizard wiz) { |
| Sources sources = (Sources) project.getLookup().lookup(org.netbeans.api.project.Sources.class); |
| SourceGroup[] sourceGroups = Util.getJavaSourceGroups(project); |
| tagHandlerSelectionPanel = new TagHandlerSelection(wiz); |
| |
| if (sourceGroups.length == 0) |
| packageChooserPanel = Templates.createSimpleTargetChooser(project, sourceGroups, tagHandlerSelectionPanel); |
| else |
| packageChooserPanel = JavaTemplates.createPackageChooser(project,sourceGroups,tagHandlerSelectionPanel); |
| |
| sourceGroups = sources.getSourceGroups(WebProjectConstants.TYPE_DOC_ROOT); |
| if (sourceGroups==null || sourceGroups.length==0) |
| sourceGroups = Util.getJavaSourceGroups(project); |
| if (sourceGroups==null || sourceGroups.length==0) |
| sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC); |
| tagInfoPanel = new TagInfoPanel(wiz, project, sourceGroups); |
| return new WizardDescriptor.Panel[] { |
| packageChooserPanel, |
| tagInfoPanel |
| }; |
| } |
| |
| public Set instantiate () throws IOException/*, IllegalStateException*/ { |
| // Here is the default plain behavior. Simply takes the selected |
| // template (you need to have included the standard second panel |
| // in createPanels(), or at least set the properties targetName and |
| // targetFolder correctly), instantiates it in the provided |
| // position, and returns the result. |
| // More advanced wizards can create multiple objects from template |
| // (return them all in the result of this method), populate file |
| // contents on the fly, etc. |
| |
| org.openide.filesystems.FileObject dir = Templates.getTargetFolder( wiz ); |
| DataFolder df = DataFolder.findFolder( dir ); |
| |
| FileObject template = Templates.getTemplate( wiz ); |
| |
| if (((TagHandlerSelection)tagHandlerSelectionPanel).isBodyTagSupport()) { |
| FileObject templateParent = template.getParent(); |
| template = templateParent.getFileObject("BodyTagHandler","java"); //NOI18N |
| } |
| DataObject dTemplate = DataObject.find( template ); |
| DataObject dobj = dTemplate.createFromTemplate( df, Templates.getTargetName( wiz ) ); |
| // writing to TLD File |
| TagInfoPanel tldPanel = (TagInfoPanel)tagInfoPanel; |
| Object[][] attrs = tldPanel.getAttributes(); |
| boolean isBodyTag = ((TagHandlerSelection)tagHandlerSelectionPanel).isBodyTagSupport(); |
| |
| // writing setters to tag handler |
| if (attrs.length>0 || isBodyTag) { |
| JavaSource clazz = JavaSource.forFileObject(dobj.getPrimaryFile()); |
| boolean evaluateBody = !((TagInfoPanel)tagInfoPanel).isEmpty(); |
| TagHandlerGenerator generator = new TagHandlerGenerator(clazz,attrs,isBodyTag, evaluateBody); |
| try { |
| generator.generate(); |
| } catch (IOException ex){ |
| LOG.log(Level.INFO, null, ex); |
| } |
| } |
| |
| //#150274 |
| Project project = Templates.getProject( wiz ); |
| ContainerClassPathModifier modifier = project.getLookup().lookup(ContainerClassPathModifier.class); |
| if (modifier != null) { |
| modifier.extendClasspath(dobj.getPrimaryFile(), new String[] { |
| ContainerClassPathModifier.API_JSP |
| }); |
| } |
| |
| |
| |
| // writing to TLD file |
| if (tldPanel.writeToTLD()) { |
| FileObject tldFo = tldPanel.getTLDFile(); |
| if (tldFo!=null) { |
| if (!tldFo.canWrite()) { |
| String mes = MessageFormat.format ( |
| NbBundle.getMessage (TagHandlerIterator.class, "MSG_tldRO"), |
| new Object [] {tldFo.getNameExt()}); |
| NotifyDescriptor desc = new NotifyDescriptor.Message(mes,NotifyDescriptor.Message.ERROR_MESSAGE); |
| DialogDisplayer.getDefault().notify(desc); |
| } else { |
| TLDDataObject tldDO = (TLDDataObject)DataObject.find(tldFo); |
| Taglib taglib=null; |
| try { |
| taglib = tldDO.getTaglib(); |
| } catch (IOException ex) { |
| String mes = MessageFormat.format ( |
| NbBundle.getMessage (TagHandlerIterator.class, "MSG_tldCorrupted"), |
| new Object [] {tldFo.getNameExt()}); |
| NotifyDescriptor desc = new NotifyDescriptor.Message(mes,NotifyDescriptor.Message.ERROR_MESSAGE); |
| DialogDisplayer.getDefault().notify(desc); |
| } |
| if (taglib!=null) { |
| WebModule wm = WebModule.getWebModule(dir); |
| if (wm != null) { |
| Profile j2eeVersion = wm.getJ2eeProfile(); |
| if (Profile.J2EE_13.equals(j2eeVersion) || Profile.J2EE_14.equals(j2eeVersion)) { |
| taglib.setDefaultNamespace(TaglibCatalog.J2EE_NS); //NOI18N |
| } |
| } |
| TagType tag = new TagType(); |
| tag.setName(tldPanel.getTagName()); |
| tag.setTagClass(tldPanel.getClassName()); |
| if (tldPanel.isEmpty()) { |
| tag.setBodyContent("empty"); //NOI18N |
| } else if (tldPanel.isScriptless()) { |
| tag.setBodyContent(isBodyTag?"JSP":"scriptless"); //NOI18N |
| } else if (tldPanel.isTegdependent()) { |
| tag.setBodyContent("tagdependent"); //NOI18N |
| } |
| //Object[][] attrs = tldPanel.getAttributes(); |
| for (int i=0;i<attrs.length;i++) { |
| TldAttributeType attr = new TldAttributeType(); |
| attr.setName((String)attrs[i][0]); |
| attr.setType((String)attrs[i][1]); |
| boolean required = ((Boolean)attrs[i][2]); |
| if (required) attr.setRequired("true"); //NOI18N |
| boolean rtexpr = ((Boolean)attrs[i][3]); |
| //if (rtexpr) attr.setRtexprvalue("true"); //NOI18N |
| // #252857 there is likely a bug in 2.1 xsd where rtexprvalue is mandatory |
| // while the docs says opposite, we chose not to fix the xsd as it |
| // is part of the JSP 2.1 spec |
| attr.setRtexprvalue(Boolean.toString(rtexpr)); |
| tag.addAttribute(attr); |
| } |
| taglib.addTag(tag); |
| SaveCookie save = (SaveCookie)tldDO.getCookie(SaveCookie.class); |
| if (save!=null) save.save(); |
| try { |
| tldDO.write(taglib); |
| } catch (IOException ex) { |
| LOG.log(Level.WARNING, null, ex); |
| } |
| } |
| } |
| } |
| } |
| |
| return Collections.singleton(dobj); |
| } |
| |
| // --- The rest probably does not need to be touched. --- |
| |
| private transient int index; |
| private transient WizardDescriptor.Panel[] panels; |
| private transient TemplateWizard wiz; |
| |
| private static final long serialVersionUID = -7586964579556513549L; |
| |
| // You can keep a reference to the TemplateWizard which can |
| // provide various kinds of useful information such as |
| // the currently selected target name. |
| // Also the panels will receive wiz as their "settings" object. |
| public void initialize (WizardDescriptor wiz) { |
| this.wiz = (TemplateWizard) wiz; |
| index = 0; |
| Project project = Templates.getProject( wiz ); |
| panels = createPanels (project,this.wiz); |
| |
| // Creating steps. |
| Object prop = wiz.getProperty (WizardDescriptor.PROP_CONTENT_DATA); // NOI18N |
| String[] beforeSteps = null; |
| if (prop != null && prop instanceof String[]) { |
| beforeSteps = (String[])prop; |
| } |
| String[] steps = Utilities.createSteps (beforeSteps, panels); |
| |
| 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(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, i); |
| // Step name (actually the whole list for reference). |
| jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, steps); |
| } |
| } |
| } |
| public void uninitialize (WizardDescriptor wiz) { |
| this.wiz = null; |
| panels = null; |
| } |
| |
| // --- WizardDescriptor.Iterator METHODS: --- |
| // Note that this is very similar to WizardDescriptor.Iterator, but with a |
| // few more options for customization. If you e.g. want to make panels appear |
| // or disappear dynamically, go ahead. |
| |
| public String name () { |
| return NbBundle.getMessage(TagHandlerIterator.class, "TITLE_x_of_y", |
| index + 1, 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) {} |
| // If something changes dynamically (besides moving between panels), |
| // e.g. the number of panels changes in response to user input, then |
| // uncomment the following and call when needed: |
| // fireChangeEvent (); |
| } |