You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by st...@apache.org on 2014/06/02 18:43:04 UTC

svn commit: r1599261 - in /sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui: nav/model/ views/

Author: stefanegli
Date: Mon Jun  2 16:43:03 2014
New Revision: 1599261

URL: http://svn.apache.org/r1599261
Log:
SLING-3606 : MVP support added

Added:
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrProperty.java   (with props)
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVNCellEditor.java   (with props)
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVPEditor.java   (with props)
Modified:
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrNode.java
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrCellLabelProvider.java
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrEditingSupport.java
    sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/PropertyTypeSupport.java

Modified: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrNode.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrNode.java?rev=1599261&r1=1599260&r2=1599261&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrNode.java (original)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrNode.java Mon Jun  2 16:43:03 2014
@@ -29,6 +29,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.jcr.PropertyType;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.PropertyDefinition;
 import javax.xml.parsers.ParserConfigurationException;
@@ -421,7 +422,7 @@ public class JcrNode implements IAdaptab
 
 	public Image getImage() {
 		boolean plainFolder = resource!=null && (resource instanceof IFolder);
-		String primaryType = getProperty("jcr:primaryType");
+		String primaryType = getProperty("jcr:primaryType").getValueAsString();
 		boolean typeFolder = primaryType!=null && ((primaryType.equals("nt:folder") || primaryType.equals("sling:Folder")));
 		boolean typeFile = primaryType!=null && ((primaryType.equals("nt:file") || primaryType.equals("nt:resource") || primaryType.equals("sling:File")));
 		typeFile |= (resource!=null && primaryType==null);
@@ -437,7 +438,7 @@ public class JcrNode implements IAdaptab
 		String mimeType = null;
 		mimeType = getJcrContentProperty("jcr:mimeType");
 		if (mimeType == null) {
-			mimeType = getProperty("jcr:mimeType");
+			mimeType = getProperty("jcr:mimeType").getValueAsString();
 		}
 		
 		if (typeUnstructured) {
@@ -481,13 +482,13 @@ public class JcrNode implements IAdaptab
 		for (int i = 0; i < chldrn.length; i++) {
 			JcrNode jcrNode = (JcrNode) chldrn[i];
 			if ("jcr:content".equals(jcrNode.getName())) {
-				return jcrNode.getProperty(propertyKey);
+				return jcrNode.getProperty(propertyKey).getValueAsString();
 			}
 		}
 		return null;
 	}
 
-	private String getProperty(String propertyKey) {
+	private String getPropertyAsString(String propertyKey) {
 		if (properties!=null) {
 			Object propertyValue = properties.getValue(propertyKey);
 			if (propertyValue!=null) {
@@ -1195,6 +1196,67 @@ public class JcrNode implements IAdaptab
         }
         return null;
     }
+    
+    public JcrProperty getProperty(final String name) {
+        if (properties==null) {
+            return null;
+        }
+        return new JcrProperty() {
+
+            @Override
+            public String getName() {
+                return name;
+            }
+
+            
+            @Override
+            public int getType() {
+                return getPropertyType(name);
+            }
+            
+            @Override
+            public String getTypeAsString() {
+                int t = getPropertyType(name);
+                return PropertyType.nameFromValue(t);
+            };
+
+//            @Override
+//            public Object getValue() {
+//                throw new IllegalStateException("not yet implemented");
+//            }
+            
+            @Override
+            public String getValueAsString() {
+                Object propertyValue = getProperties().getValue(name);
+                if (propertyValue!=null) {
+                    return String.valueOf(propertyValue);
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public boolean isMultiple() {
+                String rawValue = getProperties().getValue(name);
+                if (rawValue.startsWith("{")) {
+                    int curlyEnd = rawValue.indexOf("}", 1);
+                    rawValue = rawValue.substring(curlyEnd+1);
+                }
+                return rawValue.startsWith("[") && rawValue.endsWith("]");
+            }
+            
+            @Override
+            public String[] getValuesAsString() {
+                String rawValue = getProperties().getValue(name);
+                if (rawValue.startsWith("{")) {
+                    int curlyEnd = rawValue.indexOf("}", 1);
+                    rawValue = rawValue.substring(curlyEnd+1);
+                }
+                rawValue = rawValue.substring(1, rawValue.length()-1);
+                return org.apache.jackrabbit.util.Text.explode(rawValue, ',');
+            }
+        };
+    }
 
     public void renameProperty(String oldKey, String newKey) {
         properties.renameProperty(oldKey, newKey);

Added: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrProperty.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrProperty.java?rev=1599261&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrProperty.java (added)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrProperty.java Mon Jun  2 16:43:03 2014
@@ -0,0 +1,37 @@
+/*
+ * 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.nav.model;
+
+public interface JcrProperty {
+
+    public String getName();
+    
+    public int getType();
+    
+    public String getTypeAsString();
+    
+//    public Object getValue();
+    
+    public String getValueAsString();
+    
+    public boolean isMultiple();
+
+    public String[] getValuesAsString();
+
+
+    
+}

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/nav/model/JcrProperty.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrCellLabelProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrCellLabelProvider.java?rev=1599261&r1=1599260&r2=1599261&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrCellLabelProvider.java (original)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrCellLabelProvider.java Mon Jun  2 16:43:03 2014
@@ -23,6 +23,7 @@ import javax.jcr.PropertyType;
 import javax.jcr.nodetype.PropertyDefinition;
 
 import org.apache.sling.ide.eclipse.ui.nav.model.JcrNode;
+import org.apache.sling.ide.eclipse.ui.nav.model.JcrProperty;
 import org.eclipse.jface.viewers.CellLabelProvider;
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.ViewerCell;
@@ -83,11 +84,17 @@ public class JcrCellLabelProvider extend
                 IPropertyDescriptor pd = (IPropertyDescriptor)element;
                 JcrNode jcrNode = (JcrNode)viewer.getInput();
                 Map.Entry me = (Entry) pd.getId();
-                int propertyType = jcrNode.getPropertyType(String.valueOf(me.getKey()));
+                final String propertyName = String.valueOf(me.getKey());
+                int propertyType = jcrNode.getPropertyType(propertyName);
                 if (propertyType<=-1 || propertyType==PropertyType.UNDEFINED) {
                     cell.setText("");
                 } else {
-                    cell.setText(PropertyType.nameFromValue(propertyType));
+                    final JcrProperty property = jcrNode.getProperty(propertyName);
+                    String type = PropertyType.nameFromValue(propertyType);
+                    if (property!=null && property.isMultiple()) {
+                        type = type + "[]";
+                    }
+                    cell.setText(type);
                 }
             } else {
                 cell.setText("");
@@ -106,20 +113,34 @@ public class JcrCellLabelProvider extend
                 JcrNode jcrNode = (JcrNode)viewer.getInput();
                 Map.Entry me = (Entry) pd.getId();
                 PropertyDefinition prd = jcrNode.getPropertyDefinition(String.valueOf(me.getKey()));
-                if (prd==null) {
-                    cell.setText("false");
-                } else if (index==3) {
+                if (index==3) {
                     // protected
-                    cell.setText(String.valueOf(prd.isProtected()));
+                    if (prd!=null) {
+                        cell.setText(String.valueOf(prd.isProtected()));
+                    } else {
+                        cell.setText("false");
+                    }
                 } else if (index==4) {
                     // mandatory
-                    cell.setText(String.valueOf(prd.isMandatory()));
+                    if (prd!=null) {
+                        cell.setText(String.valueOf(prd.isMandatory()));
+                    } else {
+                        cell.setText("false");
+                    }
                 } else if (index==5) {
                     // multiple
-                    cell.setText(String.valueOf(prd.isMultiple()));
+                    if (prd!=null) {
+                        cell.setText(String.valueOf(prd.isMultiple()));
+                    } else {
+                        cell.setText(String.valueOf(jcrNode.getProperty(String.valueOf(me.getKey())).isMultiple()));
+                    }
                 } else if (index==6) {
                     // auto creatd
-                    cell.setText(String.valueOf(prd.isAutoCreated()));
+                    if (prd!=null) {
+                        cell.setText(String.valueOf(prd.isAutoCreated()));
+                    } else {
+                        cell.setText("false");
+                    }
                 } else {
                     cell.setText("n/a");
                     return;
@@ -130,19 +151,24 @@ public class JcrCellLabelProvider extend
     }
 
     private boolean canEdit(ViewerCell cell) {
+        if (cell.getColumnIndex()>2) {
+            return false;
+        }
         Object element = cell.getElement();
         if (element instanceof NewRow) {
-            return (cell.getColumnIndex()==0 || cell.getColumnIndex()==2);
+            // can edit everything of a newrow (other than type properties)
+            return true;
         } else if (element instanceof IPropertyDescriptor){
             IPropertyDescriptor pd = (IPropertyDescriptor)element;
             JcrNode jcrNode = (JcrNode)viewer.getInput();
             Map.Entry me = (Entry) pd.getId();
             if (me.getKey().equals("jcr:primaryType")) {
-                return false;
+                return cell.getColumnIndex()==2;
             } else {
                 return true;
             }
         } else {
+            // otherwise this is an unknown/unsupported cell element
             return false;
         }
     }

Modified: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrEditingSupport.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrEditingSupport.java?rev=1599261&r1=1599260&r2=1599261&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrEditingSupport.java (original)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/JcrEditingSupport.java Mon Jun  2 16:43:03 2014
@@ -23,6 +23,8 @@ import java.util.Map.Entry;
 import javax.jcr.PropertyType;
 
 import org.apache.sling.ide.eclipse.ui.nav.model.JcrNode;
+import org.apache.sling.ide.eclipse.ui.nav.model.JcrProperty;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jface.viewers.CellEditor;
 import org.eclipse.jface.viewers.ComboBoxCellEditor;
 import org.eclipse.jface.viewers.EditingSupport;
@@ -57,8 +59,8 @@ public class JcrEditingSupport extends E
         public boolean canEdit() {
             IPropertyDescriptor pd = (IPropertyDescriptor) element;
             Map.Entry me = (Entry) pd.getId();
-            if (me.getKey().equals("jcr:primaryType") && (columnId==ColumnId.NAME)) {
-                return false;
+            if (me.getKey().equals("jcr:primaryType")) {
+                return columnId==ColumnId.VALUE;
             }
             return true;
         }
@@ -132,7 +134,34 @@ public class JcrEditingSupport extends E
                 break;
             }
             case VALUE: {
-                jcrNode.setPropertyValue(me.getKey(), 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;
             }
             }
@@ -221,6 +250,9 @@ public class JcrEditingSupport extends E
 
     @Override
     protected CellEditor getCellEditor(Object element) {
+        if (!canEdit(element)) {
+            return null;
+        }
         switch(columnId) {
         case NAME: {
             // no validator needed - any string is OK
@@ -233,9 +265,13 @@ public class JcrEditingSupport extends E
             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());
+            }
             CellEditor editor = new TextCellEditor(tableViewer.getTable());
             // value might require a validator depending on the property type
-            Field field = asField(element);
             int propertyType = getNode().getPropertyType(field.getPropertyName());
             switch(propertyType) {
             case PropertyType.STRING:

Added: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVNCellEditor.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVNCellEditor.java?rev=1599261&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVNCellEditor.java (added)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVNCellEditor.java Mon Jun  2 16:43:03 2014
@@ -0,0 +1,54 @@
+/*
+ * 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 org.apache.sling.ide.eclipse.ui.nav.model.JcrNode;
+import org.apache.sling.ide.eclipse.ui.nav.model.JcrProperty;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.viewers.DialogCellEditor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+public class MVNCellEditor extends DialogCellEditor {
+
+    private final JcrNode node;
+    private final String propertyName;
+
+    public MVNCellEditor(Composite parent, JcrNode node, String propertyName) {
+        super(parent);
+        if (node==null) {
+            throw new IllegalArgumentException("node must not be null");
+        }
+        if (propertyName==null || propertyName.length()==0) {
+            throw new IllegalArgumentException("propertyName must not be null or empty");
+        }
+        this.node = node;
+        this.propertyName = propertyName;
+    }
+    
+    @Override
+    protected Object openDialogBox(Control cellEditorWindow) {
+        final JcrProperty property = node.getProperty(propertyName);
+        final MVPEditor mvpEditor = new MVPEditor(cellEditorWindow.getShell(), property);
+        if (mvpEditor.open() == IStatus.OK) {
+            return mvpEditor.getLines();
+        } else {
+            return null;
+        }
+    }
+
+}

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVNCellEditor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVPEditor.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVPEditor.java?rev=1599261&view=auto
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVPEditor.java (added)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVPEditor.java Mon Jun  2 16:43:03 2014
@@ -0,0 +1,297 @@
+/*
+ * 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.ArrayList;
+
+import org.apache.sling.ide.eclipse.ui.nav.model.JcrProperty;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.CellLabelProvider;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerCell;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+
+public class MVPEditor extends Dialog {
+
+    private final JcrProperty property;
+    private java.util.List<Line> lines = new ArrayList<MVPEditor.Line>();
+    private TableViewer viewer;
+    private final Color greyColor;
+    
+    
+    private class Line {
+
+        private String value;
+        
+        Line(String value) {
+            this.value = value;
+        }
+        
+        void setValue(String value) {
+            this.value = value;
+        }
+        
+        String getValue() {
+            return value;
+        }
+    }
+
+    protected MVPEditor(Shell parentShell, JcrProperty property) {
+        super(parentShell);
+        this.property = property;
+        if (!property.isMultiple()) {
+            throw new IllegalArgumentException("Property "+property.getName()+" is not a Multi-Value Property");
+        }
+        greyColor = new Color(parentShell.getDisplay(), 100, 100, 100);
+    }
+
+    @Override
+    protected void configureShell(Shell newShell) {
+        super.configureShell(newShell);
+        newShell.setText("Modify multi value property");
+    }
+    
+    @Override
+    protected Control createDialogArea(Composite parent) {
+        Composite composite = (Composite) super.createDialogArea(parent);
+        
+        // now add the node type dropbox-combo
+        Composite header = new Composite(composite, SWT.NONE);
+        GridLayout layout = new GridLayout();
+        layout.marginHeight = 0;
+        layout.marginWidth = 0;
+        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+        layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+        layout.numColumns = 3;
+        header.setLayout(layout);
+        
+        Label label = new Label(header, SWT.WRAP);
+        label.setText("Modify property "+property.getName()+":");
+        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());
+        
+        ToolBar buttonBar = new ToolBar(header, SWT.NONE);
+        ToolItem invisible = new ToolItem(buttonBar, SWT.NONE);
+        
+        ToolItem plus = new ToolItem(buttonBar, SWT.NONE);
+        plus.setImage(PlatformUI.getWorkbench().getSharedImages().
+                getImageDescriptor(ISharedImages.IMG_OBJ_ADD).createImage());
+        plus.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                plus();
+            }
+        });
+        
+        final ToolItem minus = new ToolItem(buttonBar, SWT.NONE);
+        minus.setImage(PlatformUI.getWorkbench().getSharedImages().
+                getImageDescriptor(ISharedImages.IMG_TOOL_DELETE).createImage());
+        minus.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                minus();
+            }
+        });
+        minus.setEnabled(false);
+
+        Composite tableParent = new Composite(composite, SWT.NONE);
+        final GridData layoutData = new GridData(GridData.FILL_BOTH);
+        layoutData.heightHint = 150;
+        tableParent.setLayoutData(layoutData);
+        TableColumnLayout tableLayout = new TableColumnLayout();
+        tableParent.setLayout(tableLayout);
+        viewer = new TableViewer(tableParent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER );
+        viewer.getTable().setLinesVisible(true);
+        viewer.getTable().setHeaderVisible(true);
+        
+        // accessing property here directly, instead of going via (JcrProperty)inputElement;
+        String[] rawLines = property.getValuesAsString();
+        // convert raw lines to Line objects for easier editing management
+        for (int i = 0; i < rawLines.length; i++) {
+            lines.add(new Line(rawLines[i]));
+        }
+        
+        viewer.setContentProvider(new IStructuredContentProvider() {
+            
+            @Override
+            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+            }
+            
+            @Override
+            public void dispose() {
+            }
+
+            @Override
+            public Object[] getElements(Object inputElement) {
+                return lines.toArray();
+            }
+        });
+        
+        TableViewerColumn column0 = new TableViewerColumn(viewer, SWT.NONE);
+        column0.getColumn().setText("Type");
+        column0.getColumn().setResizable(true);
+        column0.getColumn().setWidth(100);
+        tableLayout.setColumnData(column0.getColumn(), new ColumnWeightData(20, 100));
+        column0.setLabelProvider(new CellLabelProvider() {
+            
+            @Override
+            public void update(ViewerCell cell) {
+                try{
+                    cell.setText(property.getTypeAsString());
+                    cell.setForeground(greyColor);
+                } catch(Exception e) {
+                    cell.setText("n/a");
+                    cell.setForeground(greyColor);
+                }
+            }
+        });
+
+        TableViewerColumn column1 = new TableViewerColumn(viewer, SWT.NONE);
+        column1.getColumn().setText("Value");
+        column1.getColumn().setResizable(true);
+        column1.getColumn().setWidth(200);
+        tableLayout.setColumnData(column1.getColumn(), new ColumnWeightData(80, 200));
+
+        column1.setLabelProvider(new CellLabelProvider() {
+            
+            @Override
+            public void update(ViewerCell cell) {
+                Line line = (Line) cell.getElement();
+                cell.setText(line.getValue());
+            }
+        });
+        column1.setEditingSupport(new EditingSupport(viewer) {
+            
+            @Override
+            protected void setValue(Object element, Object value) {
+                Line line = (Line)element;
+                line.setValue(String.valueOf(value));
+                // trigger a refresh:
+                viewer.setInput(property);
+            }
+            
+            @Override
+            protected Object getValue(Object element) {
+                final Line line = (Line)element;
+                final String value = line.getValue();
+                System.out.println("Value="+value);
+                return value;
+            }
+            
+            @Override
+            protected CellEditor getCellEditor(Object element) {
+                return new TextCellEditor(viewer.getTable());
+            }
+            
+            @Override
+            protected boolean canEdit(Object element) {
+                // all values are editable
+                return true;
+            }
+        });
+        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            
+            @Override
+            public void selectionChanged(SelectionChangedEvent event) {
+                final ISelection selection = event.getSelection();
+                if (selection instanceof IStructuredSelection) {
+                    IStructuredSelection iss = (IStructuredSelection)selection;
+                    if (iss.isEmpty()) {
+                        minus.setEnabled(false);
+                    } else {
+                        minus.setEnabled(true);
+                    }
+                } else {
+                    minus.setEnabled(false);
+                }
+            }
+        });
+        
+        viewer.setInput(property);
+        
+        return composite;
+    }
+    
+    protected void minus() {
+        ISelection selection = viewer.getSelection();
+        if (selection instanceof IStructuredSelection) {
+            IStructuredSelection iss = (IStructuredSelection)selection;
+            if (!iss.isEmpty()) {
+                Object element = iss.getFirstElement();
+                if (element instanceof Line) {
+                    Line line = (Line)element;
+                    lines.remove(line);
+                }
+            }
+        }
+        viewer.setInput(property);
+    }
+
+    protected void plus() {
+        Line newLine = new Line("");
+        lines.add(newLine);
+        viewer.setInput(property);
+    }
+
+    public String[] getLines() {
+        final String[] result = new String[lines.size()];
+        for(int i=0; i<result.length; i++) {
+            result[i] = lines.get(i).getValue();
+        }
+        return result;
+    }
+    
+    @Override
+    protected void okPressed() {
+        boolean active = viewer.isCellEditorActive();
+        if (active) {
+            // force applyEditorValue to be called
+            viewer.setInput(property);
+        }
+        super.okPressed();
+    }
+}

Propchange: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/MVPEditor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/PropertyTypeSupport.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/PropertyTypeSupport.java?rev=1599261&r1=1599260&r2=1599261&view=diff
==============================================================================
--- sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/PropertyTypeSupport.java (original)
+++ sling/trunk/tooling/ide/eclipse-ui/src/org/apache/sling/ide/eclipse/ui/views/PropertyTypeSupport.java Mon Jun  2 16:43:03 2014
@@ -16,6 +16,8 @@
  */
 package org.apache.sling.ide.eclipse.ui.views;
 
+import java.net.URI;
+import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -55,11 +57,13 @@ public class PropertyTypeSupport {
     }
 
     static int propertyTypeOfIndex(int index) {
+        String name = null;
         try{
-            String name = PROPERTY_TYPES[index];
+            name = PROPERTY_TYPES[index];
             int value = PropertyType.valueFromName(name);
             return value;
         } catch(Exception e) {
+            Activator.getDefault().getPluginLogger().warn("Unsupported index ("+index+") and/or name ("+name+"): "+e, e);
             return PropertyType.STRING;
         }
     }
@@ -68,14 +72,61 @@ public class PropertyTypeSupport {
         if (!rawValue.startsWith("{")) {
             return PropertyType.STRING;
         }
-        for(int i=0; i<PROPERTY_TYPES.length; i++) {
-            if (rawValue.startsWith("{"+PROPERTY_TYPES[i]+"}")) {
-                return propertyTypeOfIndex(i);
+        int curlyEnd = rawValue.indexOf("}", 1);
+        if (curlyEnd==-1) {
+            return PropertyType.STRING;
+        }
+        String type = rawValue.substring(1, curlyEnd);
+        int index = -2;
+        try{
+            index = propertyTypeIndices.get(type);
+            return propertyTypeOfIndex(index);
+        } catch(Exception e) {
+            Activator.getDefault().getPluginLogger().warn("Unsupported type ("+type+") and/or index ("+index+"): "+e, e);
+            return PropertyType.STRING;
+        }
+    }
+
+    public static String encodeValueAsString(Object value, int propertyType) {
+        switch(propertyType) {
+        case PropertyType.BOOLEAN:
+        case PropertyType.DECIMAL:
+        case PropertyType.DOUBLE:
+        case PropertyType.LONG:
+        case PropertyType.NAME:
+        case PropertyType.PATH:
+        case PropertyType.STRING: {
+            return String.valueOf(value);
+        }
+        case PropertyType.BINARY: {
+            //TODO: how to handle binary here
+            return "";
+        }
+        case PropertyType.DATE: {
+            //TODO: double check
+            if (value instanceof GregorianCalendar) {
+                GregorianCalendar date = (GregorianCalendar)value;
+                return date.toString();
+            } else {
+                return String.valueOf(value);
+            }
+        }
+        case PropertyType.URI: {
+            if (value instanceof URI) {
+                URI uri = (URI)value;
+                return uri.toString();
+            } else {
+                return String.valueOf(value);
             }
         }
-        //TODO: hardcoded type here
-        Activator.getDefault().getPluginLogger().warn("Unsupported property type: "+rawValue);
-        return PropertyType.STRING;
+        case PropertyType.REFERENCE:
+        case PropertyType.WEAKREFERENCE: {
+            return String.valueOf(value);
+        }
+        default: {
+            return String.valueOf(value);
+        }
+        }
     }
     
 }