org.netbeans.jpa.modeler.core.widget.JavaClassWidget.java Source code

Java tutorial

Introduction

Here is the source code for org.netbeans.jpa.modeler.core.widget.JavaClassWidget.java

Source

/**
 * Copyright [2014] Gaurav Gupta
 *
 * Licensed 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.jpa.modeler.core.widget;

import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import static java.util.stream.Collectors.toList;
import javax.lang.model.SourceVersion;
import javax.swing.JOptionPane;
import org.apache.commons.lang.StringUtils;
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.widget.Widget;
import org.netbeans.jcode.core.util.SourceGroupSupport;
import org.netbeans.jcode.core.util.StringHelper;
import static org.netbeans.jcode.core.util.StringHelper.firstUpper;
import static org.netbeans.jcode.rest.controller.RESTGenerator.isAutoGeneratedEntity;
import org.netbeans.jpa.modeler.core.widget.attribute.AttributeWidget;
import org.netbeans.jpa.modeler.core.widget.flow.GeneralizationFlowWidget;
import static org.netbeans.jpa.modeler.properties.PropertiesHandler.getClassAnnoation;
import static org.netbeans.jpa.modeler.properties.PropertiesHandler.getClassSnippet;
import static org.netbeans.jpa.modeler.properties.PropertiesHandler.getCustomParentClass;
import org.netbeans.jpa.modeler.rules.entity.ClassValidator;
import org.netbeans.jpa.modeler.rules.entity.SQLKeywords;
import org.netbeans.jpa.modeler.spec.EntityMappings;
import org.netbeans.jpa.modeler.spec.extend.JavaClass;
import org.netbeans.jpa.modeler.specification.model.scene.JPAModelerScene;
import org.netbeans.jpa.modeler.specification.model.util.JPAModelerUtil;
import org.netbeans.modeler.core.ModelerFile;
import org.netbeans.modeler.specification.model.document.IColorScheme;
import org.netbeans.modeler.specification.model.document.property.ElementPropertySet;
import org.netbeans.modeler.widget.node.info.NodeWidgetInfo;
import org.netbeans.modeler.widget.pin.IPinWidget;
import org.netbeans.modeler.widget.properties.handler.PropertyChangeListener;
import org.netbeans.modules.j2ee.persistence.dd.JavaPersistenceQLKeywords;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.filesystems.FileObject;
import org.openide.util.NbBundle;
import org.openide.windows.WindowManager;
import static org.openide.util.NbBundle.getMessage;
import static org.netbeans.jpa.modeler.properties.PropertiesHandler.getCustomArtifact;
import org.netbeans.jpa.modeler.spec.IdentifiableClass;
import org.netbeans.jpa.modeler.spec.extend.Attribute;
import static org.netbeans.modeler.widget.node.IWidgetStateHandler.StateType.ERROR;
import static org.netbeans.modeler.widget.node.IWidgetStateHandler.StateType.WARNING;

public abstract class JavaClassWidget<E extends JavaClass> extends FlowNodeWidget<E, JPAModelerScene> {

    private GeneralizationFlowWidget outgoingGeneralizationFlowWidget;
    private final List<GeneralizationFlowWidget> incomingGeneralizationFlowWidgets = new ArrayList<>();

    public JavaClassWidget(JPAModelerScene scene, NodeWidgetInfo node) {
        super(scene, node);
        this.addPropertyChangeListener("class", (PropertyChangeListener<String>) (oldValue, clazz) -> {
            if (clazz == null || clazz.trim().isEmpty()) {
                JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(),
                        NbBundle.getMessage(ClassValidator.class, ClassValidator.EMPTY_CLASS_NAME));
                setName(JavaClassWidget.this.getLabel());//rollback
            } else {
                clazz = StringHelper.firstUpper(clazz);
                setName(clazz);
                setLabel(clazz);
            }
        });

        this.addPropertyChangeListener("table_name", (PropertyChangeListener<String>) (oldValue, tableName) -> {
            if (tableName != null && !tableName.trim().isEmpty()) {
                if (SQLKeywords.isSQL99ReservedKeyword(tableName)) {
                    getSignalManager().fire(WARNING, ClassValidator.CLASS_TABLE_NAME_WITH_RESERVED_SQL_KEYWORD);
                } else {
                    getSignalManager().clear(WARNING, ClassValidator.CLASS_TABLE_NAME_WITH_RESERVED_SQL_KEYWORD);
                }
            } else {
                getSignalManager().clear(WARNING, ClassValidator.CLASS_TABLE_NAME_WITH_RESERVED_SQL_KEYWORD);
            }
        });

        this.setImage(this.getNodeWidgetInfo().getModelerDocument().getImage());
        this.getImageWidget().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        this.getImageWidget().getActions().addAction(new JavaClassAction());
    }

    @Override
    public void createPropertySet(ElementPropertySet set) {
        super.createPropertySet(set);
        JavaClass javaClass = this.getBaseElementSpec();

        set.put("CLASS_STRUCTURE", getClassAnnoation(this.getModelerScene(), javaClass.getAnnotation()));
        set.put("CLASS_STRUCTURE", getCustomParentClass(this));
        set.put("CLASS_STRUCTURE",
                getCustomArtifact(this.getModelerScene(), javaClass.getInterfaces(), "Interface"));
        set.put("CLASS_STRUCTURE", getClassSnippet(this.getModelerScene(), javaClass.getSnippets()));
    }

    private final class JavaClassAction extends WidgetAction.Adapter {

        @Override
        public WidgetAction.State mousePressed(Widget widget, WidgetAction.WidgetMouseEvent event) {
            if (event.getButton() == MouseEvent.BUTTON1 && event.getClickCount() == 2) {
                openSourceCode(true);
                return WidgetAction.State.CONSUMED;
            }
            return WidgetAction.State.REJECTED;
        }
    }

    public FileObject getFileObject() {
        JavaClass javaClass = (JavaClass) this.getBaseElementSpec();
        FileObject fileObject;
        if (javaClass.getFileObject() != null) {
            fileObject = javaClass.getFileObject();
        } else {
            EntityMappings mappings = this.getModelerScene().getBaseElementSpec();
            ModelerFile modelerFile = this.getModelerScene().getModelerFile();
            fileObject = SourceGroupSupport.getJavaFileObject(modelerFile.getSourceGroup(), javaClass.getFQN());
            javaClass.setFileObject(fileObject);
        }
        return fileObject;
    }

    private void openSourceCode(boolean retryIfFileNotFound) {
        FileObject fileObject = getFileObject();
        if (fileObject == null || !fileObject.isValid()) {
            NotifyDescriptor.Confirmation msg = null;
            if (retryIfFileNotFound) {
                msg = new NotifyDescriptor.Confirmation(getMessage(this.getClass(), "SRC_FILE_NOT_FOUND.text"),
                        getMessage(this.getClass(), "SRC_FILE_NOT_FOUND.title"), NotifyDescriptor.OK_CANCEL_OPTION,
                        NotifyDescriptor.QUESTION_MESSAGE);
            } else {
                msg = new NotifyDescriptor.Confirmation(getMessage(this.getClass(), "SRC_FILE_NOT_FOUND.text"),
                        getMessage(this.getClass(), "SRC_FILE_NOT_FOUND_IN_CURRENT_PROECT.title"),
                        NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.QUESTION_MESSAGE);
            }
            if (NotifyDescriptor.YES_OPTION.equals(DialogDisplayer.getDefault().notify(msg))) {
                this.getBaseElementSpec().setGenerateSourceCode(true);
                JPAModelerUtil.generateSourceCode(this.getModelerScene().getModelerFile(), () -> {
                    openSourceCode(false);
                });
            }
        } else {
            org.netbeans.modules.openfile.OpenFile.open(fileObject, -1);
        }

    }

    public abstract void deleteAttribute(AttributeWidget attributeWidget);

    @Override
    public void deletePinWidget(IPinWidget pinWidget) {
        super.deletePinWidget(pinWidget);
        deleteAttribute((AttributeWidget) pinWidget);//  Issue Fix #5855
    }

    public abstract void sortAttributes();

    protected void validateName(String previousName, String name) {
        if (JavaPersistenceQLKeywords.isKeyword(JavaClassWidget.this.getName())) {
            getSignalManager().fire(ERROR, ClassValidator.CLASS_NAME_WITH_JPQL_KEYWORD);
        } else {
            getSignalManager().clear(ERROR, ClassValidator.CLASS_NAME_WITH_JPQL_KEYWORD);
        }
        if (isAutoGeneratedEntity(JavaClassWidget.this.getName())) {
            getSignalManager().fire(WARNING, ClassValidator.CLASS_NAME_WITH_AUTO_GEN_ENITY);
        } else {
            getSignalManager().clear(WARNING, ClassValidator.CLASS_NAME_WITH_AUTO_GEN_ENITY);
        }
        if (SourceVersion.isName(name)) {
            getSignalManager().clear(ERROR, ClassValidator.INVALID_CLASS_NAME);
        } else {
            getSignalManager().fire(ERROR, ClassValidator.INVALID_CLASS_NAME);
        }
        scanDuplicateClass(previousName, name);
        scanReservedDefaultClass(previousName, name);
    }

    public void scanDuplicateClass(String previousName, String newName) {
        int previousNameCount = 0, newNameCount = 0;
        List<JavaClassWidget> javaClassList = this.getModelerScene().getJavaClassWidges();
        EntityMappings entityMappings = this.getModelerScene().getBaseElementSpec();

        List<JavaClass> hiddenJavaClasses = new ArrayList<>(entityMappings.getJavaClass());
        hiddenJavaClasses.removeAll(
                javaClassList.stream().map(jcw -> (JavaClass) jcw.getBaseElementSpec()).collect(toList()));
        for (JavaClass javaClass : hiddenJavaClasses) {
            if (javaClass.getClazz().equals(previousName)) {
                ++previousNameCount;
            }
            if (javaClass.getClazz().equals(newName)) {
                ++newNameCount;
            }
        }

        for (JavaClassWidget<JavaClass> javaClassWidget : javaClassList) {
            JavaClass javaClass = javaClassWidget.getBaseElementSpec();

            if (javaClass.getClazz().equals(previousName)) {
                if (++previousNameCount > 1) {
                    javaClassWidget.getSignalManager().fire(ERROR, ClassValidator.NON_UNIQUE_JAVA_CLASS);
                } else if (!javaClassWidget.getSignalManager().getSignalList(ERROR).isEmpty()) {
                    javaClassWidget.getSignalManager().clear(ERROR, ClassValidator.NON_UNIQUE_JAVA_CLASS);
                }
            }

            if (javaClass.getClazz().equals(newName)) {
                if (++newNameCount > 1) {
                    javaClassWidget.getSignalManager().fire(ERROR, ClassValidator.NON_UNIQUE_JAVA_CLASS);
                } else if (!javaClassWidget.getSignalManager().getSignalList(ERROR).isEmpty()) {
                    javaClassWidget.getSignalManager().clear(ERROR, ClassValidator.NON_UNIQUE_JAVA_CLASS);
                }
            }
        }
    }

    //to fix class name
    protected String filterName(String name) {
        if (StringUtils.isNotBlank(name)) {
            name = firstUpper(name.replaceAll("\\s+", ""));
        }
        return name;
    }

    @Override
    public void setLabel(String label) {
        if (StringUtils.isNotBlank(label)) {
            this.setNodeName(filterName(label));
        }
    }

    public JavaClassWidget getSuperclassWidget() {
        if (outgoingGeneralizationFlowWidget != null) {
            return outgoingGeneralizationFlowWidget.getSuperclassWidget();
        }
        return null;
    }

    public List<JavaClassWidget> getAllSuperclassWidget() {
        List<JavaClassWidget> superclassWidgetList = new LinkedList<>();
        boolean exist = false;
        GeneralizationFlowWidget generalizationFlowWidget_TMP = this.outgoingGeneralizationFlowWidget;
        if (generalizationFlowWidget_TMP != null) {
            exist = true;
        }
        while (exist) {
            JavaClassWidget superclassWidget_Next = generalizationFlowWidget_TMP.getSuperclassWidget();
            superclassWidgetList.add(superclassWidget_Next);
            generalizationFlowWidget_TMP = superclassWidget_Next.getOutgoingGeneralizationFlowWidget();
            if (generalizationFlowWidget_TMP == null) {
                exist = false;
            }
        }
        return superclassWidgetList;
    }

    public List<JavaClassWidget> getSubclassWidgets() {
        List<JavaClassWidget> subclassWidgetList = new LinkedList<>();
        for (GeneralizationFlowWidget generalizationFlowWidget_TMP : this.incomingGeneralizationFlowWidgets) {
            JavaClassWidget subclassWidget_Nest = generalizationFlowWidget_TMP.getSubclassWidget();
            subclassWidgetList.add(subclassWidget_Nest);
        }
        return subclassWidgetList;
    }

    public List<JavaClassWidget> getAllSubclassWidgets() {
        List<JavaClassWidget> subclassWidgetList = new LinkedList<>();
        for (GeneralizationFlowWidget generalizationFlowWidget_TMP : this.incomingGeneralizationFlowWidgets) {
            JavaClassWidget subclassWidget_Nest = generalizationFlowWidget_TMP.getSubclassWidget();
            subclassWidgetList.add(subclassWidget_Nest);
            subclassWidgetList.addAll(subclassWidget_Nest.getAllSubclassWidgets());
        }
        return subclassWidgetList;
    }

    /**
     * @return the outgoingGeneralizationFlowWidget
     */
    public GeneralizationFlowWidget getOutgoingGeneralizationFlowWidget() {
        return outgoingGeneralizationFlowWidget;
    }

    /**
     * @param outgoingGeneralizationFlowWidget the
     * outgoingGeneralizationFlowWidget to set
     */
    public void setOutgoingGeneralizationFlowWidget(GeneralizationFlowWidget outgoingGeneralizationFlowWidget) {
        this.outgoingGeneralizationFlowWidget = outgoingGeneralizationFlowWidget;
    }

    /**
     * @return the incomingGeneralizationFlowWidgets
     */
    public List<GeneralizationFlowWidget> getIncomingGeneralizationFlowWidgets() {
        return incomingGeneralizationFlowWidgets;
    }

    public void addIncomingGeneralizationFlowWidget(GeneralizationFlowWidget generalizationFlowWidget) {
        incomingGeneralizationFlowWidgets.add(generalizationFlowWidget);
    }

    public void removeIncomingGeneralizationFlowWidget(GeneralizationFlowWidget generalizationFlowWidget) {
        incomingGeneralizationFlowWidgets.remove(generalizationFlowWidget);
    }

    public abstract InheritanceStateType getInheritanceState();

    public abstract InheritanceStateType getInheritanceState(boolean includeAllClass);

    ////    private static final Border WIDGET_BORDER = new ShadowBorder(new Color(255, 25, 25) ,2, new Color(255, 25, 25), new Color(255, 255, 255), new Color(255, 25, 25), new Color(255, 255, 255), new Color(255, 25, 25));
    public void showInheritancePath() {
        IColorScheme colorScheme = this.getModelerScene().getColorScheme();
        colorScheme.highlightUI(this);
        this.setHighlightStatus(true);
        //        this.setBorder(colorScheme.);
        if (this.getOutgoingGeneralizationFlowWidget() != null) {
            this.getOutgoingGeneralizationFlowWidget().setHighlightStatus(true);
            colorScheme.highlightUI(this.getOutgoingGeneralizationFlowWidget());
            //            this.getOutgoingGeneralizationFlowWidget().setForeground(Color.red);
            this.getOutgoingGeneralizationFlowWidget().getSuperclassWidget().showInheritancePath();
        }
    }

    public void hideInheritancePath() {
        IColorScheme colorScheme = this.getModelerScene().getColorScheme();
        this.setHighlightStatus(false);
        colorScheme.updateUI(this, this.getState(), this.getState());
        if (this.getOutgoingGeneralizationFlowWidget() != null) {
            this.getOutgoingGeneralizationFlowWidget().setHighlightStatus(false);
            colorScheme.updateUI(this.getOutgoingGeneralizationFlowWidget(),
                    this.getOutgoingGeneralizationFlowWidget().getState(),
                    this.getOutgoingGeneralizationFlowWidget().getState());
            this.getOutgoingGeneralizationFlowWidget().getSuperclassWidget().hideInheritancePath();
        }
    }

    public void showCompositionPath() {
        IColorScheme colorScheme = this.getModelerScene().getColorScheme();
        colorScheme.highlightUI(this);
        this.setHighlightStatus(true);
    }

    public void hideCompositionPath() {
        IColorScheme colorScheme = this.getModelerScene().getColorScheme();
        this.setHighlightStatus(false);
        colorScheme.updateUI(this, this.getState(), this.getState());
    }

    /**
     * To reserve DefaultClass name should not be used by any visual artifact
     * e.g Embeddable etc.
     *
     * @param previousName
     * @param newName
     */
    public void scanReservedDefaultClass(String previousName, String newName) {
        int previousNameCount = 0, newNameCount = 0;
        List<String> previousNameClasses = new ArrayList<>(), newNameClasses = new ArrayList<>();

        List<JavaClassWidget> javaClassList = this.getModelerScene().getJavaClassWidges();
        EntityMappings entityMappings = this.getModelerScene().getBaseElementSpec();
        for (JavaClass javaClass : entityMappings.getJavaClass()) {
            if (javaClass instanceof IdentifiableClass) {
                IdentifiableClass ic = (IdentifiableClass) javaClass;
                if (ic.getCompositePrimaryKeyType() != null && ic.getCompositePrimaryKeyClass() != null) {
                    if (ic.getCompositePrimaryKeyClass().equals(previousName)) {
                        ++previousNameCount;
                        previousNameClasses
                                .add(ic.getClazz() + ".<" + ic.getAttributes().getEmbeddedId().getName() + '>');
                    }
                    if (ic.getCompositePrimaryKeyClass().equals(newName)) {
                        ++newNameCount;
                        newNameClasses
                                .add(ic.getClazz() + ".<" + ic.getAttributes().getEmbeddedId().getName() + '>');
                    }
                }
            }
        }

        for (JavaClassWidget<JavaClass> javaClassWidget : javaClassList) {
            JavaClass javaClass = javaClassWidget.getBaseElementSpec();

            if (javaClass.getClazz().equals(previousName)) {
                if (++previousNameCount > 1) {
                    javaClassWidget.getSignalManager().fire(ERROR, ClassValidator.CLASS_NAME_USED_BY_DEFAULT_CLASS,
                            previousName, previousNameClasses.toString());
                } else if (!javaClassWidget.getSignalManager().getSignalList(ERROR).isEmpty()) {
                    javaClassWidget.getSignalManager().clear(ERROR,
                            ClassValidator.CLASS_NAME_USED_BY_DEFAULT_CLASS);
                }
            }

            if (javaClass.getClazz().equals(newName)) {
                if (++newNameCount > 1) {
                    javaClassWidget.getSignalManager().fire(ERROR, ClassValidator.CLASS_NAME_USED_BY_DEFAULT_CLASS,
                            newName, newNameClasses.toString());
                } else if (!javaClassWidget.getSignalManager().getSignalList(ERROR).isEmpty()) {
                    javaClassWidget.getSignalManager().clear(ERROR,
                            ClassValidator.CLASS_NAME_USED_BY_DEFAULT_CLASS);
                }
            }
        }
    }

    public abstract void scanDuplicateAttributes(String previousName, String newName);

    public abstract List<AttributeWidget<? extends Attribute>> getAllAttributeWidgets();

    public abstract List<AttributeWidget<? extends Attribute>> getAllAttributeWidgets(
            boolean includeParentClassAttibute);

}