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.io.IOException; 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.Map; 022 023import org.apache.avalon.framework.parameters.Parameters; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.cocoon.environment.ObjectModelHelper; 027import org.apache.cocoon.environment.Redirector; 028import org.apache.cocoon.environment.SourceResolver; 029import org.apache.commons.lang.StringUtils; 030 031import org.ametys.core.observation.AbstractNotifierAction; 032import org.ametys.core.observation.Event; 033import org.ametys.plugins.repository.AmetysObjectResolver; 034import org.ametys.plugins.repository.UnknownAmetysObjectException; 035import org.ametys.plugins.repository.metadata.ModifiableCompositeMetadata; 036import org.ametys.runtime.parameter.ParameterHelper; 037import org.ametys.web.ObservationConstants; 038import org.ametys.web.repository.page.ModifiablePage; 039import org.ametys.web.repository.page.ModifiableZone; 040import org.ametys.web.repository.page.ModifiableZoneItem; 041import org.ametys.web.repository.page.Page.PageType; 042import org.ametys.web.repository.page.ZoneItem.ZoneType; 043import org.ametys.web.service.Service; 044import org.ametys.web.service.ServiceExtensionPoint; 045import org.ametys.web.service.ServiceParameter; 046import org.ametys.web.service.ServiceParameterOrRepeater; 047import org.ametys.web.service.ServiceParameterRepeater; 048 049import com.fasterxml.jackson.core.JsonFactory; 050import com.fasterxml.jackson.core.JsonParser; 051import com.fasterxml.jackson.databind.ObjectMapper; 052 053/** 054 * This action affects a service to a zone of a page 055 * TODO To remove => use PageDAO#setService instead 056 */ 057@Deprecated 058public class ServiceAffectAction extends AbstractNotifierAction 059{ 060 /** Constant for untouched binary metadata. */ 061 public static final String UNTOUCHED_BINARY = "untouched"; 062 063 /** The list of content types */ 064 protected ServiceExtensionPoint _serviceExtensionPoint; 065 /** The Ametys object resolver */ 066 protected AmetysObjectResolver _resolver; 067 068 @Override 069 public void service(ServiceManager serviceManager) throws ServiceException 070 { 071 super.service(serviceManager); 072 _serviceExtensionPoint = (ServiceExtensionPoint) serviceManager.lookup(ServiceExtensionPoint.ROLE); 073 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 074 } 075 076 @Override 077 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 078 { 079 @SuppressWarnings("unchecked") 080 Map<String, Object> jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT); 081 082 String serviceId = (String) jsParameters.get("service-org.ametys.web.service$id"); 083 String pageId = (String) jsParameters.get("service-org.ametys.web.service$pageId"); 084 String zoneName = (String) jsParameters.get("service-org.ametys.web.service$zoneName"); 085 086 if (StringUtils.isEmpty(serviceId) || StringUtils.isEmpty(pageId) || StringUtils.isEmpty(zoneName)) 087 { 088 throw new IllegalArgumentException("ServiceId, PageId or ZoneName is not specified"); 089 } 090 091 // Check the service 092 try 093 { 094 _serviceExtensionPoint.getExtension(serviceId); 095 } 096 catch (IllegalArgumentException e) 097 { 098 throw new IllegalArgumentException("Service with id '" + serviceId + "' does not exist", e); 099 } 100 101 // Get the page 102 103 try 104 { 105 // FIXME API test if this is not modifiable 106 ModifiablePage page = _resolver.resolveById(pageId); 107 108 if (page.getType() != PageType.CONTAINER) 109 { 110 throw new IllegalArgumentException("Page '" + pageId + "' is not of type Container"); 111 } 112 113 ModifiableZone zone; 114 if (page.hasZone(zoneName)) 115 { 116 zone = page.getZone(zoneName); 117 } 118 else 119 { 120 zone = page.createZone(zoneName); 121 } 122 123 ModifiableZoneItem zoneItem = zone.addZoneItem(); 124 zoneItem.setType(ZoneType.SERVICE); 125 zoneItem.setServiceId(serviceId); 126 127 ModifiableCompositeMetadata serviceMetadata = zoneItem.getServiceParameters(); 128 Service service = _serviceExtensionPoint.getExtension(serviceId); 129 130 storeParameterValues(serviceMetadata, service, jsParameters); 131 132 page.saveChanges(); 133 134 Map<String, Object> eventParams = new HashMap<>(); 135 eventParams.put(ObservationConstants.ARGS_PAGE, page); 136 eventParams.put(ObservationConstants.ARGS_ZONE_ITEM_ID, zoneItem.getId()); 137 eventParams.put(ObservationConstants.ARGS_ZONE_TYPE, ZoneType.SERVICE); 138 _observationManager.notify(new Event(ObservationConstants.EVENT_ZONEITEM_ADDED, _getCurrentUser(), eventParams)); 139 140 Map<String, String> results = new HashMap<>(); 141 results.put("zoneitem-id", zoneItem.getId()); 142 return results; 143 } 144 catch (UnknownAmetysObjectException e) 145 { 146 throw new IllegalArgumentException("An error occured adding the service '" + serviceId + "' on the page '" + pageId + "'", e); 147 } 148 149 } 150 151 /** 152 * Store the service parameter values. 153 * @param serviceMetadata the service instance composite metadata. 154 * @param service the service definition 155 * @param values the parameter values. 156 * @throws IOException if an error occurred. 157 */ 158 protected void storeParameterValues(ModifiableCompositeMetadata serviceMetadata, Service service, Map<String, Object> values) throws IOException 159 { 160 JsonFactory jsonFactory = new JsonFactory(); 161 ObjectMapper objectMapper = new ObjectMapper(); 162 163 for (ServiceParameterOrRepeater param : service.getParameters().values()) 164 { 165 String parameterId = param.getId(); 166 Object objectValue = values.get("service-org.ametys.web.service$" + parameterId); 167 168 if (objectValue != null) 169 { 170 if (param instanceof ServiceParameter) 171 { 172 if (!UNTOUCHED_BINARY.equals(objectValue)) 173 { 174 serviceMetadata.setMetadata(parameterId, ParameterHelper.valueToString(objectValue)); 175 } 176 } 177 else if (param instanceof ServiceParameterRepeater) 178 { 179 JsonParser jParser = jsonFactory.createParser((String) objectValue); 180 ArrayList<Map<String, Object>> entries = objectMapper.readValue(jParser, ArrayList.class); 181 182 if (serviceMetadata.hasMetadata(parameterId)) 183 { 184 serviceMetadata.removeMetadata(parameterId); 185 } 186 187 ModifiableCompositeMetadata repeaterMeta = serviceMetadata.getCompositeMetadata(parameterId, true); 188 int count = 1; 189 190 for (Map<String, Object> entry : entries) 191 { 192 ModifiableCompositeMetadata entryMeta = repeaterMeta.getCompositeMetadata(Integer.toString(count++), true); 193 194 for (String childParamId : entry.keySet()) 195 { 196 Object childParamValue = entry.get(childParamId); 197 if (!UNTOUCHED_BINARY.equals(childParamValue)) 198 { 199 entryMeta.setMetadata(childParamId, ParameterHelper.valueToString(childParamValue)); 200 } 201 } 202 } 203 } 204 } 205 } 206 } 207}