Package org.apache.sling.ide.eclipse.ui.actions

Source Code of org.apache.sling.ide.eclipse.ui.actions.NewNodeDialog

/*
* 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.apache.sling.ide.eclipse.ui.actions;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;

import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;

import org.apache.sling.ide.eclipse.ui.nav.model.JcrNode;
import org.apache.sling.ide.transport.NodeTypeRegistry;
import org.apache.sling.ide.transport.RepositoryException;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class NewNodeDialog extends InputDialog {

    private static String lastChosenNodeType = null;
   
    private final String parentNodeType;
    private final NodeTypeRegistry ntManager;
    protected String comboSelection;
    private Collection<String> allowedChildren;
    private Combo combo;
    private ContentProposalAdapter proposalAdapter;
    private NodeDefinition[] allChildNodeDefs;

    public NewNodeDialog(Shell parentShell, JcrNode node,
            NodeTypeRegistry ntManager) throws RepositoryException {
        super(parentShell, "Enter Node Name",
                "Enter name for new node under:\n path: "+node.getJcrPath(), "", null);
        this.parentNodeType = node.getPrimaryType();
        this.ntManager = ntManager;
        if (ntManager!=null) {
            final LinkedList<String> ac = new LinkedList<String>(ntManager.getAllowedPrimaryChildNodeTypes(parentNodeType));
            final NodeType parentNt = ntManager.getNodeType(parentNodeType);
            allChildNodeDefs = parentNt.getChildNodeDefinitions();
            Collections.sort(ac);
            this.allowedChildren = ac;
        }
    }

    @Override
    protected Control createDialogArea(Composite parent) {
        Composite composite = (Composite) super.createDialogArea(parent);
       
        Control[] children = composite.getChildren();
        Control errorMessageText = children[children.length-1];
        GridData errorMessageGridData = new GridData(GridData.GRAB_HORIZONTAL
                | GridData.HORIZONTAL_ALIGN_FILL);
        errorMessageGridData.heightHint = convertHeightInCharsToPixels(2);
        errorMessageText.setLayoutData(errorMessageGridData);
       
        // now add the node type dropbox-combo
        Label label = new Label(composite, SWT.WRAP);
        label.moveAbove(errorMessageText);
        label.setText("Define node type");
        GridData data = new GridData(GridData.GRAB_HORIZONTAL
                | GridData.GRAB_VERTICAL | GridData.HORIZONTAL_ALIGN_FILL
                | GridData.VERTICAL_ALIGN_CENTER);
        data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
        label.setLayoutData(data);
        label.setFont(parent.getFont());

        combo = new Combo(composite, SWT.DROP_DOWN);
        combo.moveAbove(errorMessageText);
        if (allowedChildren!=null) {
            combo.setItems(allowedChildren.toArray(new String[0]));
        }
        combo.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
                | GridData.HORIZONTAL_ALIGN_FILL));
        combo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                comboSelection = combo.getText();
                validateInput();
            }
        });
        combo.addModifyListener(new ModifyListener() {

            @Override
            public void modifyText(ModifyEvent e) {
                comboSelection = combo.getText();
                validateInput();
            }
           
        });

        SimpleContentProposalProvider proposalProvider = new SimpleContentProposalProvider(combo.getItems());
        proposalProvider.setFiltering(true);
        final ComboContentAdapter controlContentAdapter = new ComboContentAdapter() {
            @Override
            public void insertControlContents(Control control, String text,
                    int cursorPosition) {
                Point selection = combo.getSelection();
                combo.setText(text);
                selection.x = selection.x + cursorPosition;
                selection.y = selection.x;
                combo.setSelection(selection);
            }
           
            @Override
            public Rectangle getInsertionBounds(Control control) {
                final Rectangle insertionBounds = super.getInsertionBounds(control);
                // always insert at start
                insertionBounds.x = 0;
                insertionBounds.y = 0;
                return insertionBounds;
            }
           
           
        };
        // this variant opens auto-complete on each character
        proposalAdapter = new ContentProposalAdapter(combo, controlContentAdapter, proposalProvider, null, null);
        // this variant opens auto-complete only when invoking the auto-complete hotkey
        if (allowedChildren!=null && allowedChildren.size()==1) {
            combo.setText(allowedChildren.iterator().next());
        } else if (allowedChildren!=null) {
            if (allowedChildren.contains(lastChosenNodeType)) {
                combo.setText(lastChosenNodeType);
            }
        }
       
        return composite;
    }
   
    @Override
    protected void initializeBounds() {
        super.initializeBounds();
        // fix autocomplete popup size:
        Point size = combo.getSize();
        size.x /= 2;
        size.y = 180;
        proposalAdapter.setPopupSize(size);
    }
   
    public String getChosenNodeType() {
        lastChosenNodeType = comboSelection;
        return comboSelection;
    }

    protected void validateInput() {
        final String firstInput = getText().getText();
        final String secondInput = comboSelection;
        try {
            if (secondInput==null || secondInput.length()==0) {
                setErrorMessage("");
            } else if (ntManager==null) {
                setErrorMessage(null);
            } else if (ntManager.isAllowedPrimaryChildNodeType(parentNodeType, secondInput)) {
                // also check on the name, not only the type
                if (allChildNodeDefs==null) {
                    setErrorMessage("No child node definitions found for "+parentNodeType);
                } else {
                    boolean success = false;
                    for (int i = 0; i < allChildNodeDefs.length; i++) {
                        NodeDefinition aChildNodeDef = allChildNodeDefs[i];
                        if (aChildNodeDef.getName()!=null && aChildNodeDef.getName().length()>0) {
                            if (firstInput.equals(aChildNodeDef.getName())) {
                                setErrorMessage(null);
                                return;
                            }
                        } else {
                            // mark success if there's a child node definition without a name
                            // (ie then it can be any name)
                            success = true;
                        }
                    }
                    if (success) {
                        setErrorMessage(null);
                        return;
                    }
                    StringBuffer details = new StringBuffer();
                    for (int i = 0; i < allChildNodeDefs.length; i++) {
                        NodeDefinition aChildNodeDef = allChildNodeDefs[i];
                        if (details.length()!=0) {
                            details.append(", ");
                        }
                        details.append("(name="+aChildNodeDef.getName()+", required primary type(s)=");
                        String[] requiredPrimaryTypeNames = aChildNodeDef.getRequiredPrimaryTypeNames();
                        if (requiredPrimaryTypeNames==null) {
                            details.append("null");
                        } else {
                            for (int j = 0; j < requiredPrimaryTypeNames.length; j++) {
                                String rptn = requiredPrimaryTypeNames[j];
                                if (j>0) {
                                    details.append(",");
                                }
                                details.append(rptn);
                            }
                        }
                        details.append(")");
                    }
                    setErrorMessage("No matching child node definition found for "+parentNodeType+". Expected one of: "+details);
                }
            } else {
                setErrorMessage("Error: Invalid child node type of "+parentNodeType);
            }
        } catch(RepositoryException e) {
            setErrorMessage("RepositoryException: "+e);
        }
       
    };
}
TOP

Related Classes of org.apache.sling.ide.eclipse.ui.actions.NewNodeDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.