001/* 002 * Copyright 2012 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 */ 016 017package org.ametys.core.util; 018 019import java.io.IOException; 020import java.io.OutputStream; 021import java.io.StringReader; 022import java.io.StringWriter; 023import java.util.ArrayList; 024import java.util.LinkedHashMap; 025import java.util.List; 026import java.util.Map; 027 028import org.apache.avalon.framework.activity.Initializable; 029import org.apache.avalon.framework.component.Component; 030import org.apache.avalon.framework.service.ServiceException; 031import org.apache.avalon.framework.service.ServiceManager; 032import org.apache.avalon.framework.service.Serviceable; 033import org.apache.avalon.framework.thread.ThreadSafe; 034import org.apache.commons.lang3.StringUtils; 035 036import org.ametys.plugins.core.ui.help.HelpSerializer; 037 038import com.fasterxml.jackson.core.JsonEncoding; 039import com.fasterxml.jackson.core.JsonFactory; 040import com.fasterxml.jackson.core.JsonGenerator; 041import com.fasterxml.jackson.core.JsonParser; 042import com.fasterxml.jackson.core.Version; 043import com.fasterxml.jackson.databind.ObjectMapper; 044import com.fasterxml.jackson.databind.module.SimpleModule; 045 046/** 047 * JSON helper 048 */ 049public class JSONUtils implements Component, ThreadSafe, Serviceable, Initializable 050{ 051 /** The avalon role */ 052 public static final String ROLE = JSONUtils.class.getName(); 053 054 private JsonFactory _jsonFactory = new JsonFactory(); 055 private ObjectMapper _objectMapper = new ObjectMapper(); 056 057 private I18nizableSerializer _i18nizableSerializer; 058 private HelpSerializer _helpSerializer; 059 private ZonedDateTimeSerializer _zoneDateTimeSerializer; 060 private LocalDateSerializer _localDateSerializer; 061 062 @Override 063 public void service(ServiceManager manager) throws ServiceException 064 { 065 _i18nizableSerializer = (I18nizableSerializer) manager.lookup(I18nizableSerializer.ROLE); 066 _zoneDateTimeSerializer = (ZonedDateTimeSerializer) manager.lookup(ZonedDateTimeSerializer.ROLE); 067 _localDateSerializer = (LocalDateSerializer) manager.lookup(LocalDateSerializer.ROLE); 068 _helpSerializer = (HelpSerializer) manager.lookup(HelpSerializer.ROLE); 069 } 070 071 @Override 072 public void initialize() throws Exception 073 { 074 // Register new serializer for I18nizableText 075 SimpleModule i18nModule = new SimpleModule("AmetysI18nModule", new Version(1, 0, 0, null, null, null)); 076 i18nModule.addSerializer(_i18nizableSerializer); 077 _objectMapper.registerModule(i18nModule); 078 079 // Register new serializer for help url 080 SimpleModule helpModule = new SimpleModule("AmetysHelpModule", new Version(1, 0, 0, null, null, null)); 081 helpModule.addSerializer(_helpSerializer); 082 _objectMapper.registerModule(helpModule); 083 084 // Register new serializer for ZonedDateTime 085 SimpleModule zoneDateTimeModule = new SimpleModule("AmetysZonedDateTimeModule", new Version(1, 0, 0, null, null, null)); 086 zoneDateTimeModule.addSerializer(_zoneDateTimeSerializer); 087 _objectMapper.registerModule(zoneDateTimeModule); 088 089 // Register new serializer for LocalDate 090 SimpleModule localDateModule = new SimpleModule("AmetysLocalDateModule", new Version(1, 0, 0, null, null, null)); 091 localDateModule.addSerializer(_localDateSerializer); 092 _objectMapper.registerModule(localDateModule); 093 } 094 095 /** 096 * Parse a JSON string to a {@link Map} object 097 * @param jsonString the string to parse 098 * @return object the infos as a Map. 099 */ 100 public Map<String, Object> convertJsonToMap (String jsonString) 101 { 102 try 103 { 104 if (StringUtils.isNotBlank(jsonString)) 105 { 106 JsonParser jParser = _jsonFactory.createParser(new StringReader(jsonString)); 107 Map<String, Object> map = _objectMapper.readValue(jParser, LinkedHashMap.class); 108 return map; 109 } 110 else 111 { 112 return new LinkedHashMap<>(); // We should not return a Collections.emptyMap() here, since we need to return a modifiable map that is always of the same type 113 } 114 } 115 catch (Exception e) 116 { 117 throw new IllegalArgumentException("The json string " + jsonString + " can not be parsed as a Map.", e); 118 } 119 } 120 121 /** 122 * Parse a JSON string to a {@link List} object. 123 * @param jsonString the string to parse. 124 * @return the infos as a List. 125 */ 126 public List<Object> convertJsonToList(String jsonString) 127 { 128 try 129 { 130 if (StringUtils.isNotBlank(jsonString)) 131 { 132 JsonParser jParser = _jsonFactory.createParser(new StringReader(jsonString)); 133 List<Object> list = _objectMapper.readValue(jParser, ArrayList.class); 134 return list; 135 } 136 else 137 { 138 return new ArrayList<>(); 139 } 140 } 141 catch (Exception e) 142 { 143 throw new IllegalArgumentException("The json string " + jsonString + " can not be parsed as a List.", e); 144 } 145 } 146 147 /** 148 * Parse a JSON string to an Object array. 149 * @param jsonString the JSON string to parse. 150 * @return the converted Object array. 151 */ 152 public Object[] convertJsonToArray(String jsonString) 153 { 154 try 155 { 156 if (StringUtils.isNotBlank(jsonString)) 157 { 158 JsonParser jParser = _jsonFactory.createParser(new StringReader(jsonString)); 159 Object[] array = _objectMapper.readValue(jParser, Object[].class); 160 return array; 161 } 162 else 163 { 164 return new Object[0]; 165 } 166 } 167 catch (Exception e) 168 { 169 throw new IllegalArgumentException("The json string " + jsonString + " can not be parsed as an array.", e); 170 } 171 } 172 173 /** 174 * Parse a JSON string to a String array. 175 * @param jsonString the JSON string to parse. 176 * @return the converted String array. 177 */ 178 public String[] convertJsonToStringArray(String jsonString) 179 { 180 try 181 { 182 if (StringUtils.isNotBlank(jsonString)) 183 { 184 JsonParser jParser = _jsonFactory.createParser(new StringReader(jsonString)); 185 String[] array = _objectMapper.readValue(jParser, String[].class); 186 return array; 187 } 188 else 189 { 190 return new String[0]; 191 } 192 } 193 catch (Exception e) 194 { 195 throw new IllegalArgumentException("The json string " + jsonString + " can not be parsed as a String array.", e); 196 } 197 } 198 199 /** 200 * Convert an object to JSON string using specified output stream. 201 * @param out The output stream 202 * @param parameters The object to convert 203 */ 204 public void convertObjectToJson (OutputStream out, Object parameters) 205 { 206 try 207 { 208 JsonGenerator jsonGenerator = _jsonFactory.createGenerator(out, JsonEncoding.UTF8); 209 _objectMapper.writeValue(jsonGenerator, parameters); 210 } 211 catch (IOException e) 212 { 213 throw new IllegalArgumentException("The object can not be converted to json string", e); 214 } 215 } 216 217 /** 218 * Convert an object to a JSON string 219 * @param parameters The object to convert (List, Map ..) 220 * @return The JSON string 221 */ 222 public String convertObjectToJson (Object parameters) 223 { 224 try 225 { 226 StringWriter writer = new StringWriter(); 227 228 JsonGenerator jsonGenerator = _jsonFactory.createGenerator(writer); 229 _objectMapper.writeValue(jsonGenerator, parameters); 230 231 return writer.toString(); 232 } 233 catch (IOException e) 234 { 235 throw new IllegalArgumentException("The object can not be converted to json string", e); 236 } 237 } 238}