001/* 002 * Copyright 2010 Anyware Services 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.ametys.web.repository.page.actions; 017 018import java.util.ArrayList; 019import java.util.Date; 020import java.util.Enumeration; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.avalon.framework.parameters.Parameters; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.cocoon.environment.ObjectModelHelper; 029import org.apache.cocoon.environment.Redirector; 030import org.apache.cocoon.environment.Request; 031import org.apache.cocoon.environment.SourceResolver; 032 033import org.ametys.core.observation.AbstractNotifierAction; 034import org.ametys.core.observation.Event; 035import org.ametys.plugins.repository.AmetysObjectResolver; 036import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata; 037import org.ametys.runtime.parameter.ParameterHelper; 038import org.ametys.runtime.parameter.ParameterHelper.ParameterType; 039import org.ametys.web.ObservationConstants; 040import org.ametys.web.repository.page.ModifiablePage; 041 042/** 043 * Edit the metadata of a page 044 * The attempt request parameters are like 'page.input.[type].[single|multiple].[path].[path]' 045 * 046 */ 047public class EditMetadataAction extends AbstractNotifierAction 048{ 049 /** Prefix for form elements. */ 050 public static final String FORM_ELEMENTS_PREFIX = "page.input."; 051 052 private AmetysObjectResolver _resolver; 053 054 @Override 055 public void service(ServiceManager smanager) throws ServiceException 056 { 057 super.service(smanager); 058 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 059 } 060 061 @Override 062 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 063 { 064 Request request = ObjectModelHelper.getRequest(objectModel); 065 String id = request.getParameter("id"); 066 067 ModifiablePage page = _resolver.resolveById(id); 068 069 // FIXME API 070 ModifiableCompositeMetadata metaHolder = page.getMetadataHolder(); 071 072 Enumeration paramNames = request.getParameterNames(); 073 while (paramNames.hasMoreElements()) 074 { 075 String paramName = (String) paramNames.nextElement(); 076 077 if (paramName.startsWith(FORM_ELEMENTS_PREFIX)) 078 { 079 String[] metadataValues = request.getParameterValues(paramName); 080 081 // ex: page.input.string.multiple.keywords.title 082 // ex: page.input.date.single.publication.date 083 paramName = paramName.substring(FORM_ELEMENTS_PREFIX.length()); 084 085 String[] a = paramName.split("\\."); 086 String type = a[0]; 087 boolean isMultiple = a[1].equals("multiple"); 088 String[] metadataPath = new String[a.length - 2]; 089 for (int i = 0; i < metadataPath.length; i++) 090 { 091 metadataPath[i] = a[i + 2]; 092 } 093 094 _saveMetadata(metaHolder, metadataPath, type, metadataValues, isMultiple); 095 } 096 } 097 098 if (page.needsSave()) 099 { 100 page.saveChanges(); 101 } 102 103 // Notify observer 104 Map<String, Object> eventParams = new HashMap<>(); 105 eventParams.put(ObservationConstants.ARGS_PAGE, page); 106 _observationManager.notify(new Event(ObservationConstants.EVENT_PAGE_CHANGED, _getCurrentUser(), eventParams)); 107 108 return EMPTY_MAP; 109 } 110 111 private void _saveMetadata (ModifiableCompositeMetadata metadata, String[] metadataPath, String type, String[] values, boolean isMultiple) 112 { 113 if (metadataPath.length == 1) 114 { 115 _saveMetadata(metadata, metadataPath[0], type, values, isMultiple); 116 } 117 else 118 { 119 String[] childPath = new String[metadataPath.length - 1]; 120 for (int i = 0; i < childPath.length; i++) 121 { 122 childPath[i] = metadataPath[i + 1]; 123 } 124 ModifiableCompositeMetadata compMetadata = metadata.getCompositeMetadata(metadataPath[0], true); 125 _saveMetadata (compMetadata, childPath, type, values, isMultiple); 126 } 127 } 128 129 private void _saveMetadata (ModifiableCompositeMetadata metadata, String metadataName, String type, String[] values, boolean isMultiple) 130 { 131 ParameterType paramType = ParameterHelper.stringToType(type); 132 133 if (ParameterType.STRING.equals(paramType)) 134 { 135 _saveStringMetadata (metadata, metadataName, values, isMultiple); 136 } 137 else if (ParameterType.DATE.equals(paramType)) 138 { 139 _saveDateMetadata (metadata, metadataName, values, isMultiple); 140 } 141 else if (ParameterType.LONG.equals(paramType)) 142 { 143 _saveLongMetadata (metadata, metadataName, values, isMultiple); 144 } 145 else if (ParameterType.DOUBLE.equals(paramType)) 146 { 147 _saveDoubleMetadata (metadata, metadataName, values, isMultiple); 148 } 149 else if (ParameterType.BOOLEAN.equals(paramType)) 150 { 151 _saveBooleanMetadata (metadata, metadataName, values, isMultiple); 152 } 153 else if (ParameterType.BINARY.equals(paramType)) 154 { 155 // TODO 156 } 157 } 158 159 private void _saveStringMetadata (ModifiableCompositeMetadata metadata, String metadataName, String[] values, boolean isMultiple) 160 { 161 List<String> stringValues = new ArrayList<>(); 162 163 for (int i = 0; i < values.length; i++) 164 { 165 if (!"".equals(values[i])) 166 { 167 stringValues.add(values[i]); 168 } 169 } 170 171 String[] stringArray = stringValues.toArray(new String[stringValues.size()]); 172 if (stringArray.length == 0) 173 { 174 if (metadata.hasMetadata(metadataName)) 175 { 176 metadata.removeMetadata(metadataName); 177 } 178 } 179 else 180 { 181 if (isMultiple) 182 { 183 metadata.setMetadata(metadataName, stringArray); 184 } 185 else 186 { 187 metadata.setMetadata(metadataName, stringArray[0]); 188 } 189 } 190 } 191 192 private void _saveDateMetadata (ModifiableCompositeMetadata metadata, String metadataName, String[] values, boolean isMultiple) 193 { 194 List<Date> dateValues = new ArrayList<>(); 195 196 for (String value : values) 197 { 198 if (!"".equals(value)) 199 { 200 Date date = (Date) ParameterHelper.castValue(value, ParameterType.DATE); 201 if (date == null) 202 { 203 getLogger().error("Cannot cast value '" + value + "' into type 'date'"); 204 throw new IllegalArgumentException("Invalid format for date value '" + value + "'"); 205 } 206 dateValues.add(date); 207 } 208 } 209 210 Date[] dateArray = dateValues.toArray(new Date[dateValues.size()]); 211 212 if (dateArray.length == 0) 213 { 214 if (metadata.hasMetadata(metadataName)) 215 { 216 metadata.removeMetadata(metadataName); 217 } 218 } 219 else 220 { 221 if (isMultiple) 222 { 223 metadata.setMetadata(metadataName, dateArray); 224 } 225 else 226 { 227 metadata.setMetadata(metadataName, dateArray[0]); 228 } 229 } 230 } 231 232 private void _saveLongMetadata (ModifiableCompositeMetadata metadata, String metadataName, String[] values, boolean isMultiple) 233 { 234 List<Long> longValues = new ArrayList<>(); 235 236 for (String value : values) 237 { 238 if (!"".equals(value)) 239 { 240 try 241 { 242 longValues.add(Long.parseLong(value)); 243 } 244 catch (NumberFormatException e) 245 { 246 getLogger().error("Cannot cast value '" + value + "' into type 'long'", e); 247 throw new IllegalArgumentException("Invalid format for long value '" + value + "'", e); 248 } 249 } 250 } 251 252 long[] longArray = new long[longValues.size()]; 253 int i = 0; 254 for (Long l : longValues) 255 { 256 longArray[i] = l.longValue(); 257 i++; 258 } 259 260 if (longArray.length == 0) 261 { 262 if (metadata.hasMetadata(metadataName)) 263 { 264 metadata.removeMetadata(metadataName); 265 } 266 } 267 else 268 { 269 if (isMultiple) 270 { 271 metadata.setMetadata(metadataName, longArray); 272 } 273 else 274 { 275 metadata.setMetadata(metadataName, longArray[0]); 276 } 277 } 278 279 } 280 281 private void _saveDoubleMetadata (ModifiableCompositeMetadata metadata, String metadataName, String[] values, boolean isMultiple) 282 { 283 List<Double> doubleValues = new ArrayList<>(); 284 285 for (String value : values) 286 { 287 if (!"".equals(value)) 288 { 289 try 290 { 291 doubleValues.add(Double.parseDouble(value)); 292 } 293 catch (NumberFormatException e) 294 { 295 getLogger().error("Cannot cast value '" + value + "' into type 'double'", e); 296 throw new IllegalArgumentException("Invalid format for double value '" + value + "'", e); 297 } 298 } 299 } 300 301 double[] doubleArray = new double[doubleValues.size()]; 302 int i = 0; 303 for (Double d : doubleValues) 304 { 305 doubleArray[i] = d.doubleValue(); 306 i++; 307 } 308 309 310 if (doubleArray.length == 0) 311 { 312 if (metadata.hasMetadata(metadataName)) 313 { 314 metadata.removeMetadata(metadataName); 315 } 316 } 317 else 318 { 319 if (isMultiple) 320 { 321 metadata.setMetadata(metadataName, doubleArray); 322 } 323 else 324 { 325 metadata.setMetadata(metadataName, doubleArray[0]); 326 } 327 } 328 } 329 330 private void _saveBooleanMetadata (ModifiableCompositeMetadata metadata, String metadataName, String[] values, boolean isMultiple) 331 { 332 List<Boolean> booleanValues = new ArrayList<>(); 333 334 for (String value : values) 335 { 336 if (!"".equals(value)) 337 { 338 booleanValues.add(Boolean.parseBoolean(value)); 339 } 340 } 341 342 boolean[] booleanArray = new boolean[booleanValues.size()]; 343 int i = 0; 344 for (Boolean b : booleanValues) 345 { 346 booleanArray[i] = b.booleanValue(); 347 i++; 348 } 349 350 if (booleanArray.length == 0) 351 { 352 if (metadata.hasMetadata(metadataName)) 353 { 354 metadata.removeMetadata(metadataName); 355 } 356 } 357 else 358 { 359 if (isMultiple) 360 { 361 metadata.setMetadata(metadataName, booleanArray); 362 } 363 else 364 { 365 metadata.setMetadata(metadataName, booleanArray[0]); 366 } 367 } 368 } 369}