| /* |
| * 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.php.editor.codegen; |
| |
| import java.awt.Dialog; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.prefs.Preferences; |
| import javax.swing.ComboBoxModel; |
| import javax.swing.DefaultComboBoxModel; |
| import javax.swing.JPanel; |
| import javax.swing.text.JTextComponent; |
| import org.netbeans.api.project.FileOwnerQuery; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.ProjectUtils; |
| import org.netbeans.lib.editor.codetemplates.api.CodeTemplate; |
| import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager; |
| import org.netbeans.modules.editor.NbEditorUtilities; |
| import org.netbeans.modules.php.editor.codegen.ui.ConstructorPanel; |
| import org.netbeans.modules.php.editor.codegen.ui.MethodPanel; |
| import org.netbeans.spi.editor.codegen.CodeGenerator; |
| import org.openide.DialogDescriptor; |
| import org.openide.DialogDisplayer; |
| import org.openide.filesystems.FileObject; |
| import org.openide.util.Lookup; |
| import org.openide.util.NbBundle; |
| |
| /** |
| * |
| * @author Petr Pisl |
| */ |
| public final class CGSGenerator implements CodeGenerator { |
| |
| static final String START_OF_GETTER = "get"; //NOI18N |
| static final String START_OF_SETTER = "set"; //NOI18N |
| static final String NEW_LINE = System.getProperty("line.separator"); //NOI18N |
| static final String UNDERSCORED_METHOD_NAME = "${UNDERSCORED_METHOD_NAME}"; //NOI18N |
| static final String ACCESS_MODIFIER = "${MODIFIER}"; //NOI18N |
| static final String ACCESSOR = "${ACCESSOR}"; //NOI18N |
| static final String PROPERTY = "${PROPERTY}"; //NOI18N |
| static final String PARAM_NAME = "${PARAM_NAME}"; //NOI18N |
| static final String UP_FIRST_LETTER_PROPERTY = "${UpFirstLetterProperty}"; //NOI18N |
| static final String UP_FIRST_LETTER_PROPERTY_WITHOUT_UNDERSCORE = "${UpFirstLetterPropertyWithoutUnderscore}"; //NOI18N |
| static final String ASSIGNMENT_TEMPLATE = NEW_LINE + ACCESSOR + PROPERTY + " = $" + PARAM_NAME + ";"; //NOI18N |
| private static final String CURSOR = "${cursor}"; //NOI18N |
| private static final String PROPERTY_WITHOUT_UNDERSCORE = "${PropertyWithoutUnderscore}"; //NOI18N |
| private static final String PARAMS = "${PARAMS}"; //NOI18N |
| private static final String ASSIGNMENTS = "${ASSIGNMENT}"; //NOI18N |
| private static final String CONSTRUCTOR_TEMPLATE = ACCESS_MODIFIER + "function __construct(" + PARAMS + ") {" + ASSIGNMENTS + CURSOR + NEW_LINE + "}" + NEW_LINE; //NOI18N |
| |
| public enum GenType { |
| CONSTRUCTOR(Panel.CONSTRUCTOR, Visibility.INVISIBLE, Visibility.VISIBLE) { |
| |
| @Override |
| public String getPanelTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_PANEL_CONSTRUCTOR"); //NOI18N |
| } |
| |
| @Override |
| public ComboBoxModel getModel(final String propertyName) { |
| final DefaultComboBoxModel result = new DefaultComboBoxModel(); |
| for (CGSGenerator.GenWay way : CGSGenerator.GenWay.values()) { |
| if (!way.equals(CGSGenerator.GenWay.WITH_UNDERSCORE)) { |
| result.addElement(new ComboBoxModelElement(way.getSimpleDescription() + ": " + way.getConstructorExample(propertyName), way)); //NOI18N |
| } |
| } |
| return result; |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_CONSTRUCTOR"); //NOI18N |
| } |
| |
| @Override |
| public String getDialogTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_TITLE_CONSTRUCTOR"); //NOI18N |
| } |
| |
| @Override |
| public String getTemplateText(final CGSInfo cgsInfo) { |
| final StringBuilder params = new StringBuilder(); |
| final StringBuilder assignments = new StringBuilder(); |
| for (Property property : cgsInfo.getProperties()) { |
| final String name = property.getName(); |
| final String paramName = cgsInfo.getHowToGenerate() == GenWay.WITHOUT_UNDERSCORE |
| ? CodegenUtils.withoutUnderscore(name) : name; |
| if (property.isSelected()) { |
| params.append(", "); //NOI18N |
| String type = property.getType(); |
| if (type != null && !type.isEmpty()) { |
| params.append(property.getTypeForTemplate()); |
| } |
| params.append("$").append(paramName); //NOI18N |
| assignments.append(ASSIGNMENT_TEMPLATE.replace(PROPERTY, name).replace(PARAM_NAME, paramName).replace(ACCESSOR, property.getAccessor())); |
| } |
| } |
| if (params.length() == 0) { |
| params.append(", "); //NOI18N |
| } |
| String accessModifier = cgsInfo.isPublicModifier() ? "public " : ""; //NOI18N |
| return CONSTRUCTOR_TEMPLATE.replace(ACCESS_MODIFIER, accessModifier) |
| .replace(PARAMS, params.toString().substring(2)) |
| .replace(ASSIGNMENTS, assignments); |
| } |
| |
| }, |
| GETTER(Panel.CONSTRUCTOR, Visibility.INVISIBLE, Visibility.VISIBLE) { |
| |
| @Override |
| public String getPanelTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_PANEL_GETTERS"); //NOI18N |
| } |
| |
| @Override |
| public ComboBoxModel getModel(final String propertyName) { |
| final DefaultComboBoxModel result = new DefaultComboBoxModel(); |
| for (CGSGenerator.GenWay way : CGSGenerator.GenWay.values()) { |
| result.addElement(new ComboBoxModelElement(way.getSimpleDescription() + ": " + way.getGetterExample(propertyName), way)); //NOI18N |
| } |
| return result; |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_GETTER"); //NOI18N |
| } |
| |
| @Override |
| public String getDialogTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_TITLE_GETTERS"); //NOI18N |
| } |
| |
| @Override |
| public String getTemplateText(final CGSInfo cgsInfo) { |
| return new SelectedPropertyMethodsCreator().create(cgsInfo.getPossibleGetters(), new SinglePropertyMethodCreator.SingleGetterCreator(cgsInfo)); |
| } |
| |
| }, |
| SETTER(Panel.CONSTRUCTOR, Visibility.VISIBLE, Visibility.VISIBLE) { |
| |
| @Override |
| public String getPanelTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_PANEL_SETTERS"); //NOI18N |
| } |
| |
| @Override |
| public ComboBoxModel getModel(final String propertyName) { |
| final DefaultComboBoxModel result = new DefaultComboBoxModel(); |
| for (CGSGenerator.GenWay way : CGSGenerator.GenWay.values()) { |
| result.addElement(new ComboBoxModelElement(way.getSimpleDescription() + ": " + way.getSetterExample(propertyName), way)); |
| } |
| return result; |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_SETTER"); //NOI18N |
| } |
| |
| @Override |
| public String getDialogTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_TITLE_SETTERS"); //NOI18N |
| } |
| |
| @Override |
| public String getTemplateText(final CGSInfo cgsInfo) { |
| return new SelectedPropertyMethodsCreator().create(cgsInfo.getPossibleSetters(), new SinglePropertyMethodCreator.SingleSetterCreator(cgsInfo)); |
| } |
| |
| }, |
| GETTER_AND_SETTER(Panel.CONSTRUCTOR, Visibility.VISIBLE, Visibility.VISIBLE) { |
| |
| @Override |
| public String getPanelTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_PANEL_GETTERS_AND_SETTERS"); //NOI18N |
| } |
| |
| @Override |
| public ComboBoxModel getModel(final String propertyName) { |
| final DefaultComboBoxModel result = new DefaultComboBoxModel(); |
| for (CGSGenerator.GenWay way : CGSGenerator.GenWay.values()) { |
| result.addElement(new ComboBoxModelElement( |
| way.getSimpleDescription() |
| + ": " + way.getGetterExample(propertyName) |
| + ", " + way.getSetterExample(propertyName), way)); //NOI18N |
| } |
| return result; |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_GETTER_AND_SETTER"); //NOI18N |
| } |
| |
| @Override |
| public String getDialogTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_TITLE_GETTERS_AND_SETTERS"); //NOI18N |
| } |
| |
| @Override |
| public String getTemplateText(final CGSInfo cgsInfo) { |
| final StringBuilder gettersAndSetters = new StringBuilder(); |
| gettersAndSetters.append(new SelectedPropertyMethodsCreator().create(cgsInfo.getPossibleGetters(), new SinglePropertyMethodCreator.SingleGetterCreator(cgsInfo))); |
| gettersAndSetters.append(new SelectedPropertyMethodsCreator().create(cgsInfo.getPossibleSetters(), new SinglePropertyMethodCreator.SingleSetterCreator(cgsInfo))); |
| return gettersAndSetters.toString(); |
| } |
| |
| }, |
| METHODS(Panel.METHOD, Visibility.INVISIBLE, Visibility.INVISIBLE) { |
| |
| @Override |
| public String getPanelTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_PANEL_METHODS"); //NOI18N |
| } |
| |
| @Override |
| public ComboBoxModel getModel(final String propertyName) { |
| return new DefaultComboBoxModel(); |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_METHOD"); //NOI18N |
| } |
| |
| @Override |
| public String getDialogTitle() { |
| return NbBundle.getMessage(CGSGenerator.class, "LBL_TITLE_METHODS"); //NOI18N |
| } |
| |
| @Override |
| public String getTemplateText(final CGSInfo cgsInfo) { |
| return new SelectedPropertyMethodsCreator().create(cgsInfo.getPossibleMethods(), new SinglePropertyMethodCreator.InheritedMethodCreator(cgsInfo)); |
| } |
| |
| }; |
| |
| private final Panel panel; |
| private final Visibility fluentSetter; |
| private final Visibility publicModifier; |
| |
| public abstract String getPanelTitle(); |
| public abstract ComboBoxModel getModel(final String propertyName); |
| public abstract String getDisplayName(); |
| public abstract String getDialogTitle(); |
| public abstract String getTemplateText(final CGSInfo cgsInfo); |
| |
| private GenType(final Panel panel, Visibility fluentSetter, Visibility publicModifier) { |
| this.panel = panel; |
| this.fluentSetter = fluentSetter; |
| this.publicModifier = publicModifier; |
| } |
| |
| public JPanel createPanel(final CGSInfo cgsInfo) { |
| return panel.createPanel(this, cgsInfo); |
| } |
| |
| public boolean isFluentSetterVisible() { |
| return fluentSetter.isVisible(); |
| } |
| |
| public boolean isPublicModifierVisible() { |
| return publicModifier.isVisible(); |
| } |
| |
| private enum Panel { |
| CONSTRUCTOR { |
| @Override |
| JPanel createPanel(final GenType genType, final CGSInfo cgsInfo) { |
| return new ConstructorPanel(genType, cgsInfo); |
| } |
| }, |
| METHOD { |
| @Override |
| JPanel createPanel(final GenType genType, final CGSInfo cgsInfo) { |
| return new MethodPanel(cgsInfo); |
| } |
| }; |
| |
| abstract JPanel createPanel(final GenType genType, final CGSInfo cgsInfo); |
| } |
| |
| private enum Visibility { |
| VISIBLE { |
| @Override |
| boolean isVisible() { |
| return true; |
| } |
| }, |
| INVISIBLE { |
| @Override |
| boolean isVisible() { |
| return false; |
| } |
| }; |
| |
| abstract boolean isVisible(); |
| } |
| |
| } |
| |
| public enum GenWay { |
| AS_JAVA( |
| NbBundle.getMessage(CGSGenerator.class, "JAVA_STYLE"), |
| "__construct($" + PROPERTY + ")", |
| START_OF_GETTER + UP_FIRST_LETTER_PROPERTY, |
| START_OF_SETTER + UP_FIRST_LETTER_PROPERTY), //NOI18N |
| WITH_UNDERSCORE( |
| NbBundle.getMessage(CGSGenerator.class, "ADD_UNDERSCORE"), |
| "__construct($" + PROPERTY + ")", |
| START_OF_GETTER + "_" + UNDERSCORED_METHOD_NAME, |
| START_OF_SETTER + "_" + UNDERSCORED_METHOD_NAME), //NOI18N |
| WITHOUT_UNDERSCORE( |
| NbBundle.getMessage(CGSGenerator.class, "REMOVE_UNDERSCORE"), |
| "__construct($" + PROPERTY_WITHOUT_UNDERSCORE + ")", |
| START_OF_GETTER + UP_FIRST_LETTER_PROPERTY_WITHOUT_UNDERSCORE, |
| START_OF_SETTER + UP_FIRST_LETTER_PROPERTY_WITHOUT_UNDERSCORE); //NOI18N |
| |
| private final String constructorTemplate; |
| private final String getterTemplate; |
| private final String setterTemplate; |
| /** |
| * The description will appear in the ui combobox. |
| */ |
| private final String simpleDescription; |
| |
| private GenWay(String simpleDescription, String constructorTemplate, String getterTemplate, String setterTemplate) { |
| this.constructorTemplate = constructorTemplate; |
| this.getterTemplate = getterTemplate; |
| this.setterTemplate = setterTemplate; |
| this.simpleDescription = simpleDescription; |
| } |
| |
| public String getConstructorTemplate() { |
| return constructorTemplate; |
| } |
| |
| public String getGetterTemplate() { |
| return getterTemplate; |
| } |
| |
| public String getSetterTemplate() { |
| return setterTemplate; |
| } |
| |
| public String getSimpleDescription() { |
| return simpleDescription; |
| } |
| |
| public String getConstructorExample(String property) { |
| return createExample(getConstructorTemplate(), property); |
| } |
| |
| public String getGetterExample(String property) { |
| return createExample(getGetterTemplate(), property); |
| } |
| |
| public String getSetterExample(String property) { |
| return createExample(getSetterTemplate(), property); |
| } |
| |
| private String createExample(String template, String property) { |
| String example = template; |
| if (template.contains(PROPERTY)) { |
| example = example.replace(PROPERTY, property); |
| } |
| if (template.contains(UNDERSCORED_METHOD_NAME)) { |
| example = example.replace(UNDERSCORED_METHOD_NAME, property); |
| } |
| if (template.contains(UP_FIRST_LETTER_PROPERTY)) { |
| example = example.replace(UP_FIRST_LETTER_PROPERTY, CodegenUtils.upFirstLetter(property)); |
| } |
| if (template.contains(UP_FIRST_LETTER_PROPERTY_WITHOUT_UNDERSCORE)) { |
| example = example.replace(UP_FIRST_LETTER_PROPERTY_WITHOUT_UNDERSCORE, CodegenUtils.upFirstLetterWithoutUnderscore(property)); |
| } |
| if (template.contains(PROPERTY_WITHOUT_UNDERSCORE)) { |
| example = example.replace(PROPERTY_WITHOUT_UNDERSCORE, CodegenUtils.withoutUnderscore(property)); |
| } |
| return example; |
| } |
| } |
| |
| //constructor |
| private final GenType genType; |
| private final CGSInfo cgsInfo; |
| |
| private static final String GETTER_SETTER_PROJECT_PROPERTY = "getter.setter.method.name.generation"; //NOI18N |
| private static final String FLUENT_SETTER_PROJECT_PROPERTY = "fluent.setter.project.property"; //NOI18N |
| private static final String PUBLIC_MODIFIER_PROJECT_PROPERTY = "public.modifier.project.property"; //NOI18N |
| |
| private CGSGenerator(CGSInfo cgsInfo, GenType type) { |
| this.genType = type; |
| this.cgsInfo = cgsInfo; |
| } |
| |
| @Override |
| public void invoke() { |
| // obtain the generation from project properties |
| JTextComponent component = cgsInfo.getComponent(); |
| FileObject fo = NbEditorUtilities.getFileObject(component.getDocument()); |
| Preferences preferences = null; |
| Project project = FileOwnerQuery.getOwner(fo); |
| if (project != null) { |
| preferences = ProjectUtils.getPreferences(project, CGSGenerator.class, false); |
| try { |
| cgsInfo.setHowToGenerate(GenWay.valueOf(preferences.get(GETTER_SETTER_PROJECT_PROPERTY, GenWay.AS_JAVA.name()))); |
| } catch (IllegalArgumentException ex) { |
| cgsInfo.setHowToGenerate(GenWay.AS_JAVA); |
| } |
| cgsInfo.setFluentSetter(preferences.getBoolean(FLUENT_SETTER_PROJECT_PROPERTY, false)); |
| cgsInfo.setPublicModifier(preferences.getBoolean(PUBLIC_MODIFIER_PROJECT_PROPERTY, false)); |
| } |
| DialogDescriptor desc = new DialogDescriptor(genType.createPanel(cgsInfo), genType.getDialogTitle()); |
| Dialog dialog = DialogDisplayer.getDefault().createDialog(desc); |
| dialog.setVisible(true); |
| dialog.dispose(); |
| if (desc.getValue() == DialogDescriptor.OK_OPTION) { |
| CodeTemplateManager manager = CodeTemplateManager.get(component.getDocument()); |
| CodeTemplate template = manager.createTemporary(genType.getTemplateText(cgsInfo)); |
| template.insert(component); |
| if (preferences != null) { |
| //save the gen type value to the project properties |
| preferences.put(GETTER_SETTER_PROJECT_PROPERTY, cgsInfo.getHowToGenerate().name()); |
| preferences.putBoolean(FLUENT_SETTER_PROJECT_PROPERTY, cgsInfo.isFluentSetter()); |
| preferences.putBoolean(PUBLIC_MODIFIER_PROJECT_PROPERTY, cgsInfo.isPublicModifier()); |
| } |
| } |
| } |
| |
| @Override |
| public String getDisplayName() { |
| return genType.getDisplayName(); |
| } |
| |
| public static class Factory implements CodeGenerator.Factory { |
| |
| @Override |
| public List<? extends CodeGenerator> create(Lookup context) { |
| JTextComponent textComp = context.lookup(JTextComponent.class); |
| ArrayList<CodeGenerator> ret = new ArrayList<>(); |
| CGSInfo info = CGSInfo.getCGSInfo(textComp); |
| |
| if (info.getClassName() != null) { // is the cursor in a class? |
| if (!info.hasConstructor()) { |
| ret.add(new CGSGenerator(info, GenType.CONSTRUCTOR)); |
| } |
| if (info.getPossibleGetters().size() > 0) { |
| ret.add(new CGSGenerator(info, GenType.GETTER)); |
| } |
| if (info.getPossibleSetters().size() > 0) { |
| ret.add(new CGSGenerator(info, GenType.SETTER)); |
| } |
| if (info.getPossibleGettersSetters().size() > 0) { |
| ret.add(new CGSGenerator(info, GenType.GETTER_AND_SETTER)); |
| } |
| if (info.getPossibleMethods().size() > 0) { |
| ret.add(new CGSGenerator(info, GenType.METHODS)); |
| } |
| } |
| return ret; |
| } |
| } |
| |
| } |