001/* 002 * Copyright 2011 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.skinfactory.parameters; 017 018import java.io.IOException; 019import java.io.OutputStream; 020import java.nio.charset.StandardCharsets; 021import java.nio.file.Files; 022import java.nio.file.Path; 023import java.util.HashMap; 024import java.util.Map; 025import java.util.regex.Matcher; 026import java.util.regex.Pattern; 027 028import org.apache.cocoon.xml.AttributesImpl; 029import org.apache.cocoon.xml.XMLUtils; 030import org.apache.commons.io.IOUtils; 031import org.xml.sax.ContentHandler; 032import org.xml.sax.SAXException; 033 034import org.ametys.runtime.i18n.I18nizableText; 035import org.ametys.web.skin.SkinModel; 036 037/** 038 * Implementation of {@link AbstractSkinParameter} for a i18niable text 039 */ 040public class TextParameter extends AbstractSkinParameter 041{ 042 private String _defaultValue; 043 private Path _xslFile; 044 045 /** 046 * Constructor 047 * @param id the unique id 048 * @param label the label 049 * @param description the description 050 * @param xslFile the XSL file 051 * @param defaultValue the default value in the default language 052 */ 053 public TextParameter(String id, I18nizableText label, I18nizableText description, Path xslFile, String defaultValue) 054 { 055 super(id, label, description); 056 _xslFile = xslFile; 057 _defaultValue = defaultValue; 058 } 059 060 /** 061 * Get the CSS file path 062 * @return the CSS file path 063 */ 064 public Path getPath () 065 { 066 return _xslFile; 067 } 068 069 @Override 070 public SkinParameterType getType() 071 { 072 return SkinParameterType.TEXT; 073 } 074 075 @Override 076 public void apply(Path tempDir, Path modelDir, Object value, String lang) 077 { 078 String relPath = modelDir.relativize(_xslFile).toString(); 079 Path cssFile = tempDir.resolve(relPath); 080 String string = _filetoString(cssFile); 081 082 Pattern pattern = Pattern.compile("^[^>]*>([^<]*)<!--\\s*AMETYS\\s*\\(\\s*\"([^\"]+)\"\\s*(?:,\\s*([^,\"\\s]+|\"[^\"]*\")\\s*)?(?:,\\s*([^,\"\\s]+|\"[^\"]*\")\\s*)?\\)\\s*-->.*$$", Pattern.MULTILINE); 083 Matcher matcher = pattern.matcher(string); 084 085 try (OutputStream os = Files.newOutputStream(cssFile)) 086 { 087 int startIndex = 0; 088 089 while (matcher.find()) 090 { 091 int propertyStart = matcher.start(1); 092 093 String beforeValue = string.substring(startIndex, propertyStart); 094 IOUtils.write(beforeValue, os, "UTF-8"); 095 IOUtils.write((String) value, os, "UTF-8"); 096 097 startIndex = matcher.end(1); 098 } 099 100 IOUtils.write(string.substring(startIndex), os, "UTF-8"); 101 } 102 catch (IOException e) 103 { 104 throw new SkinParameterException ("Unable to apply text parameter '" + getId() + "'", e); 105 } 106 } 107 108 private String _filetoString (Path file) 109 { 110 try 111 { 112 return Files.readString(file, StandardCharsets.UTF_8); 113 } 114 catch (IOException e) 115 { 116 throw new SkinParameterException ("Unable to parse file '" + file.getFileName().toString() + "'", e); 117 } 118 } 119 120 @Override 121 public void toSAX(ContentHandler contentHandler, String modelName) throws SAXException 122 { 123 AttributesImpl attrs = new AttributesImpl(); 124 attrs.addCDATAAttribute("id", getId()); 125 attrs.addCDATAAttribute("type", SkinParameterType.TEXT.name().toLowerCase()); 126 127 XMLUtils.startElement(contentHandler, "parameter", attrs); 128 129 getLabel().toSAX(contentHandler, "label"); 130 getDescription().toSAX(contentHandler, "description"); 131 132 XMLUtils.endElement(contentHandler, "parameter"); 133 134 } 135 136 @Override 137 public Map<String, Object> toJson(String modelName) 138 { 139 Map<String, Object> jsonObject = new HashMap<>(); 140 141 jsonObject.put("id", getId()); 142 jsonObject.put("type", SkinParameterType.TEXT.name().toLowerCase()); 143 jsonObject.put("label", getLabel()); 144 jsonObject.put("description", getDescription()); 145 146 return jsonObject; 147 } 148 149 @Override 150 public String getDefaultValue(SkinModel model) 151 { 152 return _defaultValue; 153 } 154 155 @Override 156 public String getDefaultValue(SkinModel model, String lang) 157 { 158 return getDefaultValue(model); 159 } 160}