001/* 002 * Copyright 2015 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.skin.actions; 017 018import java.nio.file.Path; 019import java.util.Collection; 020import java.util.Collections; 021import java.util.HashMap; 022import java.util.Map; 023 024import org.apache.avalon.framework.context.Context; 025import org.apache.avalon.framework.context.ContextException; 026import org.apache.avalon.framework.context.Contextualizable; 027import org.apache.avalon.framework.parameters.Parameters; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.cocoon.acting.ServiceableAction; 031import org.apache.cocoon.environment.ObjectModelHelper; 032import org.apache.cocoon.environment.Redirector; 033import org.apache.cocoon.environment.Request; 034import org.apache.cocoon.environment.SourceResolver; 035import org.apache.commons.lang3.StringUtils; 036 037import org.ametys.core.cocoon.JSonReader; 038import org.ametys.runtime.model.DefinitionAndValue; 039import org.ametys.runtime.model.DefinitionContext; 040import org.ametys.runtime.model.ElementDefinition; 041import org.ametys.runtime.model.ModelItem; 042import org.ametys.runtime.model.View; 043import org.ametys.runtime.model.type.DataContext; 044import org.ametys.runtime.util.AmetysHomeHelper; 045import org.ametys.web.skin.Skin; 046import org.ametys.web.skin.SkinDAO; 047import org.ametys.web.skin.SkinParameterTypeExtensionPoint; 048import org.ametys.web.skin.SkinParametersModel; 049import org.ametys.web.skin.SkinsManager; 050 051/** 052 * Get the skin configuration parameters and their values 053 */ 054public class SkinConfigurationAction extends ServiceableAction implements Contextualizable 055{ 056 /** The service manager instance */ 057 private SkinsManager _skinsManager; 058 private Context _context; 059 private SkinParameterTypeExtensionPoint _skinParameterTypeEP; 060 private SkinDAO _skinDAO; 061 062 @Override 063 public void service(ServiceManager serviceManager) throws ServiceException 064 { 065 super.service(serviceManager); 066 _skinsManager = (SkinsManager) serviceManager.lookup(SkinsManager.ROLE); 067 _skinParameterTypeEP = (SkinParameterTypeExtensionPoint) serviceManager.lookup(SkinParameterTypeExtensionPoint.ROLE); 068 _skinDAO = (SkinDAO) serviceManager.lookup(SkinDAO.ROLE); 069 } 070 071 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 072 { 073 Request request = ObjectModelHelper.getRequest(objectModel); 074 075 String skinName = request.getParameter("skinName"); 076 String tempDir = request.getParameter("tempDir"); 077 String skinDirName = request.getParameter("skinDir"); 078 079 Path skinDir = null; 080 if (StringUtils.isEmpty(tempDir)) 081 { 082 Skin skin = _skinsManager.getSkin(skinName); 083 if (!skin.isConfigurable()) 084 { 085 throw new IllegalStateException("The skin '" + skinName + "' is not configurable."); 086 } 087 088 skinDir = skin.getRawPath(); // isConfigurable does not support inheritance. fine to edit local file thus 089 } 090 else 091 { 092 Path ametysTmpDir = AmetysHomeHelper.getAmetysHomeTmp().toPath(); 093 skinDir = ametysTmpDir.resolve(tempDir).resolve(skinDirName); 094 } 095 096 SkinParametersModel model = new SkinParametersModel(skinName, skinDir, _skinParameterTypeEP, _context, manager); 097 Map<String, Object> result = new HashMap<>(); 098 099 View view = model.getView(); 100 result.put("parameters", view.toJSON(DefinitionContext.newInstance().withEdition(true))); 101 102 result.put("values", _values2json(skinDir, model.getModelItems())); 103 104 request.setAttribute(JSonReader.OBJECT_TO_READ, result); 105 return Collections.EMPTY_MAP; 106 } 107 108 /** 109 * Read configuration file and return a flat map of values 110 * @param skinDir The skin directory 111 * @param skinParameterDefinitions The parameters definitions 112 * @return the configuration definition and values 113 * @throws Exception if a problem occurs reading values 114 */ 115 private Map<String, Object> _values2json(Path skinDir, Collection<ElementDefinition> skinParameterDefinitions) throws Exception 116 { 117 Collection<DefinitionAndValue> definitionAndValues = _skinDAO.readValues(skinDir, skinParameterDefinitions); 118 119 Map<String, Object> values = new HashMap<>(); 120 121 if (definitionAndValues != null) 122 { 123 for (DefinitionAndValue definitionAndValue : definitionAndValues) 124 { 125 ModelItem definition = definitionAndValue.getDefinition(); 126 127 // Skin parameter can only be element definitions 128 if (definition instanceof ElementDefinition) 129 { 130 ElementDefinition elementDefinition = (ElementDefinition) definition; 131 Object jsonValue = elementDefinition.getType().valueToJSONForClient(definitionAndValue.getValue(), DataContext.newInstance()); 132 values.put(elementDefinition.getName(), jsonValue); 133 } 134 } 135 } 136 137 Map<String, Object> form = new HashMap<>(); 138 form.put("values", values); 139 return form; 140 } 141 142 public void contextualize(Context context) throws ContextException 143 { 144 _context = context; 145 } 146 147}