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

Source Code of org.apache.sling.ide.eclipse.ui.views.JcrEditingSupport$DecimalValidator

/*
* 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.views;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.jcr.PropertyType;

import org.apache.sling.ide.eclipse.core.ServerUtil;
import org.apache.sling.ide.eclipse.ui.nav.model.JcrNode;
import org.apache.sling.ide.eclipse.ui.nav.model.JcrProperty;
import org.apache.sling.ide.eclipse.ui.nav.model.JcrTextPropertyDescriptor;
import org.apache.sling.ide.eclipse.ui.nav.model.ModifiableProperties;
import org.apache.sling.ide.transport.NodeTypeRegistry;
import org.apache.sling.ide.transport.Repository;
import org.apache.sling.ide.transport.RepositoryException;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.SimpleContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;

public class JcrEditingSupport extends EditingSupport {
   
    static enum ColumnId {
        NAME, TYPE, VALUE, MULTIPLE
    }

    private final ColumnId columnId;
    private final TableViewer tableViewer;
    private final JcrPropertiesView view;
   
    private class Field {
        private final Object element;

        Field(Object element) {
            this.element = element;
        }

        public boolean canEdit() {
            IPropertyDescriptor pd = (IPropertyDescriptor) element;
            Map.Entry me = (Entry) pd.getId();
            if (me.getKey().equals("jcr:primaryType")) {
                return columnId==ColumnId.VALUE;
            }
            return true;
        }
       
        public Object getValue() {
            IPropertyDescriptor pd = (IPropertyDescriptor) element;
            JcrNode jcrNode = getNode();
            Map.Entry me = (Entry) pd.getId();
           
            switch(columnId) {
            case NAME: {
                return String.valueOf(me.getKey());
            }
            case TYPE: {
                final int propertyType = getNode().getPropertyType(getPropertyName());
                if (propertyType!=-1) {
                    return PropertyTypeSupport.indexOfPropertyType(propertyType);
                } else {
                    //TODO: otherwise hardcode to STRING
                    return PropertyTypeSupport.indexOfPropertyType(PropertyType.STRING);
                }
            }
            case VALUE: {
                final int propertyType = getNode().getPropertyType(getPropertyName());
                String rawValue = String.valueOf(me.getValue());
                int index = rawValue.indexOf("}");
                if (index!=-1) {
                    rawValue = rawValue.substring(index+1);
                }
                if ((propertyType!=-1) && (propertyType==PropertyType.BOOLEAN)) {
                    try{
                        if (Boolean.parseBoolean(String.valueOf(rawValue))) {
                            return 1;
                        } else {
                            return 0;
                        }
                    } catch(Exception e) {
                        return 0;
                    }
                } else if ((propertyType!=-1) && (propertyType!=PropertyType.STRING)) {
                    return rawValue;
                }
                return String.valueOf(me.getValue());
            }
            case MULTIPLE: {
                boolean isMultiple = getNode().getProperty(getPropertyName()).isMultiple();
                return isMultiple ? 1 : 0;
            }
            default: {
                throw new IllegalStateException("Unknown columnId: "+columnId);
            }
            }
        }
       
        public String getPropertyName() {
            IPropertyDescriptor pd = (IPropertyDescriptor) element;
            Map.Entry me = (Entry) pd.getId();
            return String.valueOf(me.getKey());
        }

        public void setValue(Object element, Object value) {
            if (getValue().equals(value)) {
                // then ignore this
                return;
            }
            JcrTextPropertyDescriptor pd = (JcrTextPropertyDescriptor) element;
            JcrNode jcrNode = getNode();
            Map.Entry me = (Entry) pd.getId();
           
            switch(columnId) {
            case NAME: {
                final String oldKey = String.valueOf(getValue());
                final String newKey = String.valueOf(value);
                pd.setNewPropertyName(newKey);
                Map<String, String> pseudoMap = new HashMap<String, String>();
                final String propertyValue = jcrNode.getProperties().getValue(oldKey);
                pseudoMap.put(newKey, propertyValue);
                final Entry<String, String> mapEntry = pseudoMap.entrySet().iterator().next();
                element = new TextPropertyDescriptor(mapEntry, propertyValue);
                jcrNode.renameProperty(oldKey, newKey);
                break;
            }
            case TYPE: {
                int propertyType = PropertyTypeSupport.propertyTypeOfIndex((Integer)value);
                jcrNode.changePropertyType(String.valueOf(me.getKey()), propertyType);
                break;
            }
            case VALUE: {
                try{
                    final JcrProperty property = getNode().getProperty(getPropertyName());
                    final int propertyType = property.getType();
                    String encodedValue;
                    if (property.isMultiple()) {
                        Object[] values = (Object[])value;
                        encodedValue = "";
                        for (int i = 0; i < values.length; i++) {
                            Object aValue = values[i];
                            String aValueAsString = PropertyTypeSupport.encodeValueAsString(aValue, propertyType);
                            if (i==0) {
                                encodedValue = aValueAsString;
                            } else {
                                encodedValue = encodedValue+","+aValueAsString;
                            }
                        }
                        encodedValue = "["+encodedValue+"]";
                    } else {
                        encodedValue = PropertyTypeSupport.encodeValueAsString(value, propertyType);
                    }
                    if (propertyType!=PropertyType.STRING && propertyType!=PropertyType.NAME) {
                        encodedValue = "{"+PropertyType.nameFromValue(propertyType)+"}"+encodedValue;
                    }
                    jcrNode.setPropertyValue(me.getKey(), encodedValue);
                } catch(Exception e) {
                    // emergency fallback
                    jcrNode.setPropertyValue(me.getKey(), String.valueOf(value));
                }
                break;
            }
            case MULTIPLE: {
                if (!(value instanceof Integer)) {
                    // value must be an integer
                    return;
                }
                final Integer newIsMultipleValue = (Integer) value;
                final boolean newIsMultiple = newIsMultipleValue==1;
                final JcrProperty property = getNode().getProperty(getPropertyName());
                final boolean oldIsMultiple = property.isMultiple();
                if (newIsMultiple==oldIsMultiple) {
                    // then nothing is to be done
                    return;
                }
                final String oldPropertyValue = getNode().getProperties().getValue(getPropertyName());
                // split {type} prefix from value
                int cPos = oldPropertyValue.indexOf("}");
                final String prefix;
                final String rawValue;
                if (cPos==-1) {
                    prefix = "";
                    rawValue = oldPropertyValue;
                } else {
                    prefix = oldPropertyValue.substring(0, cPos+1);
                    rawValue = oldPropertyValue.substring(cPos+1);
                }
                String newValue;
                if (newIsMultiple) {
                    newValue = prefix + "[" + rawValue + "]";
                } else {
                    newValue = rawValue.substring(1, rawValue.length()-1);
                    int commaPos = newValue.indexOf(",");
                    if (commaPos!=-1) {
                        newValue = newValue.substring(0, commaPos);
                    }
                    newValue = prefix + newValue;
                }
                jcrNode.setPropertyValue(getPropertyName(), newValue);
                break;
            }
            }

            view.refreshContent();
        }

        public int getPropertyType() {
            IPropertyDescriptor pd = (IPropertyDescriptor) element;
            Map.Entry me = (Entry) pd.getId();
            String value = String.valueOf(me.getValue());
            return PropertyTypeSupport.propertyTypeOfString(value);
        }

        public String getNewPropertyName() {
            JcrTextPropertyDescriptor pd = (JcrTextPropertyDescriptor) element;
            if (pd.getNewPropertyName()!=null) {
                return pd.getNewPropertyName();
            } else {
                return getPropertyName();
            }
        }
    }
   
    private class NewRowField extends Field {

        private final NewRow newRow;

        NewRowField(NewRow newRow) {
            super(newRow);
            this.newRow = newRow;
        }
       
        @Override
        public boolean canEdit() {
            return true;
        }
       
        @Override
        public int getPropertyType() {
            return newRow.getType();
        }
       
        @Override
        public Object getValue() {
            if (columnId==ColumnId.NAME) {
                return newRow.getName();
            } else if (columnId==ColumnId.VALUE) {
                final int propertyType = newRow.getType();
                if (propertyType==PropertyType.BOOLEAN) {
                    try{
                        if (Boolean.parseBoolean(String.valueOf(newRow.getValue()))) {
                            return 1;
                        } else {
                            return 0;
                        }
                    } catch(Exception e) {
                        return 0;
                    }
                }
                return newRow.getValue();
            } else if (columnId==ColumnId.TYPE) {
                final int propertyType = newRow.getType();
                if (propertyType!=-1) {
                    return PropertyTypeSupport.indexOfPropertyType(propertyType);
                } else {
                    //TODO: otherwise hardcode to STRING
                    return PropertyTypeSupport.indexOfPropertyType(PropertyType.STRING);
                }
            } else if (columnId==ColumnId.MULTIPLE) {
                //TODO
                return 0;
            } else {
                return null;
            }
        }
       
        @Override
        public String getPropertyName() {
            return String.valueOf(newRow.getName());
        }
       
        @Override
        public String getNewPropertyName() {
            return getPropertyName();
        }
       
        @Override
        public void setValue(Object element, Object value) {
            if (getValue().equals(value)) {
                // then ignore this
                return;
            }
            if (columnId==ColumnId.NAME) {
                String newName = String.valueOf(value);
                ModifiableProperties props = getNode().getProperties();
                int cnt = 1;
                while(props.getValue(newName)!=null) {
                    newName = String.valueOf(value)+(cnt++);
                }
                newRow.setName(newName);
            } else if (columnId==ColumnId.VALUE) {
                newRow.setValue(PropertyTypeSupport.encodeValueAsString(value, getPropertyType()));
            } else if (columnId==ColumnId.TYPE) {
                int propertyType = PropertyTypeSupport.propertyTypeOfIndex((Integer)value);
                newRow.setType(propertyType);
            } else if (columnId==ColumnId.MULTIPLE) {
                // do nothing at the moment
                //TODO
            } else {
                // otherwise non-editable
                return;
            }
            handleNewRowUpdate(newRow);
        }
    }
   
    private class DecimalValidator implements ICellEditorValidator {

        private final CellEditor editor;

        DecimalValidator(CellEditor editor) {
            this.editor = editor;
        }
       
        @Override
        public String isValid(Object value) {
            Control cn = editor.getControl();
            TableViewer tw = tableViewer;
            Color red = new Color(Display.getCurrent(), new RGB(255, 100, 100));
            cn.setBackground(red);
            return null;
        }
       
    }

    public JcrEditingSupport(JcrPropertiesView view, TableViewer viewer, ColumnId columnType) {
        super(viewer);
        this.view = view;
        this.columnId = columnType;
        this.tableViewer = viewer;
    }

    @Override
    protected CellEditor getCellEditor(Object element) {
        try{
            final CellEditor result = doGetCellEditor(element);
            if (result!=null) {
                Field field = asField(element);
                view.setLastValueEdited(field.getPropertyName(), field.getNewPropertyName(), columnId);
            }
            return result;
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
    }
   
    protected CellEditor doGetCellEditor(Object element) {
        if (!canEdit(element)) {
            return null;
        }
        switch(columnId) {
        case NAME: {
            // no validator needed - any string is OK
            return new TextCellEditor(tableViewer.getTable());
        }
        case TYPE: {
            // using a dropdown editor
            final ComboBoxCellEditor editor = new ComboBoxCellEditor(tableViewer.getTable(),
                    PropertyTypeSupport.PROPERTY_TYPES, SWT.NONE);
            editor.setActivationStyle(ComboBoxCellEditor.DROP_DOWN_ON_KEY_ACTIVATION |
                    ComboBoxCellEditor.DROP_DOWN_ON_MOUSE_ACTIVATION |
                    ComboBoxCellEditor.DROP_DOWN_ON_TRAVERSE_ACTIVATION);
            return editor;
        }
        case VALUE: {
            final Field field = asField(element);
            if (getNode().getProperty(field.getPropertyName()).isMultiple()) {
                // then launch the MVPEditor instead of returning an editor here
                return new MVNCellEditor(tableViewer.getTable(), getNode(), field.getPropertyName());
            }
            if (field.getPropertyType()==PropertyType.DATE) {
                return new DateTimeCellEditor(tableViewer.getTable(), getNode(), field.getPropertyName());
            }
            if (field.getPropertyType()==PropertyType.BOOLEAN) {
                return new ComboBoxCellEditor(tableViewer.getTable(), new String[] {"false", "true"}, SWT.READ_ONLY);
            }
            CellEditor editor;
            if (field.getPropertyName().equals("jcr:primaryType")) {
                editor = new TextCellEditor(tableViewer.getTable()) {
                    @Override
                    protected Control createControl(Composite parent) {
                        Text text = (Text) super.createControl(parent);
                        Repository repository = ServerUtil.getDefaultRepository(getNode().getProject());
                        NodeTypeRegistry ntManager = (repository==null) ? null : repository.getNodeTypeRegistry();
                        if (ntManager == null) {
                            return text;
                        }
                        try {
                            Collection<String> types = ntManager.getAllowedPrimaryChildNodeTypes(getNode().getParent().getPrimaryType());
                            SimpleContentProposalProvider proposalProvider = new SimpleContentProposalProvider(types.toArray(new String[0]));
                            proposalProvider.setFiltering(true);
                            ContentProposalAdapter adapter = new ContentProposalAdapter(text, new TextContentAdapter(),
                                    proposalProvider, null, null);
                            adapter.setPropagateKeys(true);
                            adapter
                                    .setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
                            return text;
                        } catch (RepositoryException e) {
                            return text;
                        }
                    }
                };
            } else {
                editor = new TextCellEditor(tableViewer.getTable());
            }
            // value might require a validator depending on the property type
            int propertyType = getNode().getPropertyType(field.getPropertyName());
            switch(propertyType) {
            case PropertyType.STRING:
            case PropertyType.NAME: {
                // no validator needed, any string is OK (for now)
                //TODO: check jcr rules for name
                break;
            }
            case PropertyType.DECIMAL: {
                editor.setValidator(new DecimalValidator(editor));
                break;
            }
            default: {
                // for the rest, no check implemented yet
                //TODO
                break;
            }
            }
            return editor;
        }
        case MULTIPLE: {
            if (element instanceof NewRow) {
                return null;
            }
            return new ComboBoxCellEditor(tableViewer.getTable(), new String[] {"false", "true"}, SWT.READ_ONLY);
        }
        default: {
            throw new IllegalStateException("Unknown columnId: "+columnId);
        }
        }
    }

    @Override
    protected boolean canEdit(Object element) {
        return asField(element).canEdit();
    }
   
    private Field asField(Object element) {
        if (element instanceof NewRow) {
            return new NewRowField((NewRow)element);
        } else {
            return new Field(element);
        }
    }

    @Override
    protected Object getValue(Object element) {
        return asField(element).getValue();
    }

    @Override
    protected void setValue(Object element, Object value) {
        Field field = asField(element);
        if (!field.canEdit()) {
            return;
        }
        String newPropertyName;
        if (columnId==ColumnId.NAME) {
            newPropertyName = String.valueOf(value);
        } else {
            newPropertyName = field.getPropertyName();
        }
        view.setLastValueEdited(field.getPropertyName(), newPropertyName, columnId);
        field.setValue(element, value);
    }

    void handleNewRowUpdate(NewRow newRow) {
        if (newRow.isComplete()) {
            tableViewer.remove(newRow);
            final JcrNode jcrNode = (JcrNode)tableViewer.getInput();
            final Integer type = newRow.getType();
            String encodeValueAsString = PropertyTypeSupport.encodeValueAsString(newRow.getValue(), type);
            if (type!=PropertyType.STRING && type!=PropertyType.NAME) {
                encodeValueAsString = "{"+PropertyType.nameFromValue(type)+"}"+encodeValueAsString;
            }
            final String propertyName = String.valueOf(newRow.getName());
            jcrNode.addProperty(propertyName, encodeValueAsString);
            view.refreshContent();
        } else {
            tableViewer.update(newRow, null);
        }
    }

    private JcrNode getNode() {
        return (JcrNode)tableViewer.getInput();
    }
   
}
TOP

Related Classes of org.apache.sling.ide.eclipse.ui.views.JcrEditingSupport$DecimalValidator

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.