001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.web.client.peditor; 017 018import com.google.gwt.user.client.rpc.AsyncCallback; 019import com.smartgwt.client.types.Alignment; 020import com.smartgwt.client.types.MultipleAppearance; 021import com.smartgwt.client.types.VerticalAlignment; 022import com.smartgwt.client.util.SC; 023import com.smartgwt.client.widgets.Button; 024import com.smartgwt.client.widgets.Label; 025import com.smartgwt.client.widgets.events.ClickHandler; 026import com.smartgwt.client.widgets.form.DynamicForm; 027import com.smartgwt.client.widgets.form.fields.SelectItem; 028import com.smartgwt.client.widgets.form.fields.events.ClickEvent; 029import com.smartgwt.client.widgets.layout.VLayout; 030import java.util.ArrayList; 031import org.modeshape.web.client.contents.Contents; 032import org.modeshape.web.shared.Align; 033import org.modeshape.web.shared.Columns; 034import org.modeshape.web.shared.JcrNode; 035 036/** 037 * Default value editor which is using text representation of the value. 038 * 039 * @author kulikov 040 */ 041public class MixinValueEditor extends BaseEditor implements ValueEditor<String> { 042 //form title 043 private final static String TITLE = "Modify property value"; 044 045 //form dimensions 046 private final static int WIDTH = 430; 047 private final static int HEIGHT = 350; 048 049 //form fields 050 private final SelectItem mixTypes = new SelectItem(""); 051 private final SelectItem selectedTypes = new SelectItem(""); 052 053 //'controller' - provides access to business logic 054 private final Contents contents; 055 056 //node/property references 057 private JcrNode node; 058 private String name; 059 060 private String[] allTypes; 061 private String[] nodeTypes; 062 private String[] originalNodeTypes; 063 064 /** 065 * Creates this property editor. 066 * 067 * @param contents Contents view form. 068 */ 069 public MixinValueEditor(Contents contents) { 070 super(TITLE); 071 this.contents = contents; 072 073 setWidth(WIDTH); 074 setHeight(HEIGHT); 075 076 Columns h1 = new Columns(Align.CENTER, Align.CENTER); 077 h1.setHeight(15); 078 079 Label l1 = new Label(); 080 l1.setWidth(150); 081 l1.setContents("Mixin Types"); 082 083 Label l2 = new Label(); 084 l2.setWidth(100); 085 l2.setContents(""); 086 087 Label l3 = new Label(); 088 l3.setWidth(150); 089 l3.setContents("Node's types"); 090 091 h1.addMember(l1); 092 h1.addMember(l2); 093 h1.addMember(l3); 094 095 addMember(h1); 096 097 Columns layout = new Columns(Align.CENTER, Align.CENTER); 098 layout.setWidth100(); 099 100 mixTypes.setMultiple(true); 101 mixTypes.setMultipleAppearance(MultipleAppearance.GRID); 102 mixTypes.setWidth(150); 103 mixTypes.setHeight(200); 104 105 selectedTypes.setMultiple(true); 106 selectedTypes.setMultipleAppearance(MultipleAppearance.GRID); 107 selectedTypes.setWidth(150); 108 selectedTypes.setHeight(200); 109 110 DynamicForm f1 = new DynamicForm(); 111 f1.setItems(mixTypes); 112 f1.setWidth(150); 113 f1.setHeight(200); 114 115 DynamicForm f2 = new DynamicForm(); 116 f2.setItems(selectedTypes); 117 f2.setWidth(150); 118 f2.setHeight(200); 119 120 VLayout buttons = new VLayout(); 121 buttons.setLayoutAlign(Alignment.CENTER); 122 buttons.setDefaultLayoutAlign(Alignment.CENTER); 123 buttons.setAlign(Alignment.CENTER); 124 buttons.setLayoutAlign(VerticalAlignment.CENTER); 125 buttons.setWidth(50); 126 127 layout.addMember(f1); 128 layout.addMember(buttons); 129 layout.addMember(f2); 130 131 Button b1 = new Button(">>"); 132 b1.setWidth(30); 133 b1.addClickHandler(new ClickHandler() { 134 @Override 135 public void onClick(com.smartgwt.client.widgets.events.ClickEvent event) { 136 allTypes = remove(allTypes, mixTypes.getValueAsString()); 137 nodeTypes = add(nodeTypes, mixTypes.getValueAsString()); 138 updateLists(); 139 } 140 }); 141 142 Button b2 = new Button("<<"); 143 b2.setWidth(30); 144 b2.addClickHandler(new ClickHandler() { 145 @Override 146 public void onClick(com.smartgwt.client.widgets.events.ClickEvent event) { 147 nodeTypes = remove(nodeTypes, selectedTypes.getValueAsString()); 148 allTypes = add(allTypes, selectedTypes.getValueAsString()); 149 updateLists(); 150 } 151 }); 152 153 buttons.addMember(b1); 154 buttons.addMember(b2); 155 156 addMember(layout); 157 158 Columns h3 = new Columns(Align.RIGHT, Align.CENTER); 159 h3.setHeight(50); 160 161 Button okButton = new Button("OK"); 162 okButton.addClickHandler(new ClickHandler() { 163 @Override 164 public void onClick(com.smartgwt.client.widgets.events.ClickEvent event) { 165 onConfirm(null); 166 hide(); 167 } 168 }); 169 170 Button cancelButton = new Button("Cancel"); 171 cancelButton.addClickHandler(new ClickHandler() { 172 @Override 173 public void onClick(com.smartgwt.client.widgets.events.ClickEvent event) { 174 hide(); 175 } 176 }); 177 178 h3.addMember(okButton); 179 h3.addMember(cancelButton); 180 181 addMember(h3); 182 183 } 184 185 @Override 186 public void showModal() { 187 contents.jcrService().getMixinTypes(contents.repository(), contents.workspace(), 188 false, new AsyncCallback<String[]>() { 189 @Override 190 public void onFailure(Throwable caught) { 191 SC.say(caught.getMessage()); 192 } 193 194 @Override 195 public void onSuccess(String[] result) { 196 allTypes = result; 197 updateLists(); 198 MixinValueEditor.super.showModal(); 199 } 200 }); 201 202 } 203 204 private void updateLists() { 205 mixTypes.setValueMap(diff(allTypes, nodeTypes)); 206 selectedTypes.setValueMap(diff(nodeTypes, allTypes)); 207 } 208 209 private String[] parseValues(String value) { 210 if (value.equalsIgnoreCase("N/A")) { 211 return new String[]{}; 212 } 213 return value.split(","); 214 } 215 216 @Override 217 public void setValue(JcrNode node, String name, String value) { 218 this.node = node; 219 this.name = name; 220 221 nodeTypes = parseValues(value); 222 originalNodeTypes = parseValues(value); 223 224 showModal(); 225 } 226 227 private String[] remove(String[] values, String value) { 228 String[] res = new String[values.length - 1]; 229 int j = 0; 230 for (int i = 0; i < values.length; i++) { 231 if (!values[i].equalsIgnoreCase(value)) { 232 res[j++] = values[i]; 233 } 234 } 235 return res; 236 } 237 238 private String[] add(String[] values, String value) { 239 String[] res = new String[values.length + 1]; 240 for (int i = 0; i < values.length; i++) { 241 res[i] = values[i]; 242 } 243 res[values.length] = value; 244 return res; 245 } 246 247 @SuppressWarnings("unchecked") 248 private String[] diff(String[] a, String[] b) { 249 ArrayList<String> list = new ArrayList(); 250 for (int i = 0; i < a.length; i++) { 251 boolean found = false; 252 for (int j = 0; j < b.length; j++) { 253 if (a[i].equalsIgnoreCase(b[j])) { 254 found = true; 255 break; 256 } 257 } 258 if (!found) list.add(a[i]); 259 } 260 String[] map = new String[list.size()]; 261 list.toArray(map); 262 return map; 263 } 264 265 @Override 266 public void onConfirm(ClickEvent event) { 267 //new types 268 for (int i = 0; i < nodeTypes.length; i++) { 269 boolean isNew = true; 270 271 for (int j = 0; j < originalNodeTypes.length; j++) { 272 if (nodeTypes[i].equalsIgnoreCase(originalNodeTypes[j])) { 273 isNew = false; 274 break; 275 } 276 } 277 278 if (isNew) contents.addMixin(nodeTypes[i]); 279 } 280 281 //removed types 282 for (int i = 0; i < originalNodeTypes.length; i++) { 283 boolean isRemoved = false; 284 285 for (int j = 0; j < nodeTypes.length; j++) { 286 if (originalNodeTypes[i].equalsIgnoreCase(nodeTypes[j])) { 287 isRemoved = false; 288 break; 289 } 290 } 291 292 if (isRemoved) contents.removeMixin(nodeTypes[i]); 293 } 294 } 295 296}