001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.json.jabsorb.serializer;
016    
017    import com.liferay.portal.kernel.util.Validator;
018    
019    import java.util.Locale;
020    
021    import org.jabsorb.serializer.AbstractSerializer;
022    import org.jabsorb.serializer.MarshallException;
023    import org.jabsorb.serializer.ObjectMatch;
024    import org.jabsorb.serializer.SerializerState;
025    import org.jabsorb.serializer.UnmarshallException;
026    
027    import org.json.JSONObject;
028    
029    /**
030     * @author Raymond Aug??
031     */
032    public class LocaleSerializer extends AbstractSerializer {
033    
034            @Override
035            public boolean canSerialize(
036                    @SuppressWarnings("rawtypes") Class clazz,
037                    @SuppressWarnings("rawtypes") Class jsonClazz) {
038    
039                    if (Locale.class.isAssignableFrom(clazz) &&
040                            ((jsonClazz == null) || (jsonClazz == JSONObject.class))) {
041    
042                            return true;
043                    }
044    
045                    return false;
046            }
047    
048            @Override
049            public Class<?>[] getJSONClasses() {
050                    return _JSON_CLASSES;
051            }
052    
053            @Override
054            public Class<?>[] getSerializableClasses() {
055                    return _SERIALIZABLE_CLASSES;
056            }
057    
058            @Override
059            public Object marshall(
060                            SerializerState serializerState, Object parentObject, Object object)
061                    throws MarshallException {
062    
063                    JSONObject jsonObject = new JSONObject();
064    
065                    if (ser.getMarshallClassHints()) {
066                            try {
067                                    Class<?> javaClass = object.getClass();
068    
069                                    jsonObject.put("javaClass", javaClass.getName());
070                            }
071                            catch (Exception e) {
072                                    throw new MarshallException("Unable to put javaClass", e);
073                            }
074                    }
075    
076                    JSONObject localeJSONObject = new JSONObject();
077    
078                    try {
079                            jsonObject.put("locale", localeJSONObject);
080    
081                            serializerState.push(object, localeJSONObject, "locale");
082                    }
083                    catch (Exception e) {
084                            throw new MarshallException("Unable to put locale", e);
085                    }
086    
087                    try {
088                            Locale locale = (Locale)object;
089    
090                            localeJSONObject.put("country", locale.getCountry());
091                            localeJSONObject.put("language", locale.getLanguage());
092                            localeJSONObject.put("variant", locale.getVariant());
093                    }
094                    catch (Exception e) {
095                            throw new MarshallException(
096                                    "Unable to put country, language, and variant", e);
097                    }
098                    finally {
099                            serializerState.pop();
100                    }
101    
102                    return jsonObject;
103            }
104    
105            @Override
106            public ObjectMatch tryUnmarshall(
107                            SerializerState serializerState,
108                            @SuppressWarnings("rawtypes") Class clazz, Object object)
109                    throws UnmarshallException {
110    
111                    JSONObject localeJSONObject = getLocaleJSONObject(object);
112    
113                    ObjectMatch objectMatch = ObjectMatch.ROUGHLY_SIMILAR;
114    
115                    if (localeJSONObject.has("language")) {
116                            objectMatch = ObjectMatch.OKAY;
117                    }
118    
119                    serializerState.setSerialized(object, objectMatch);
120    
121                    return objectMatch;
122            }
123    
124            @Override
125            public Object unmarshall(
126                            SerializerState serializerState,
127                            @SuppressWarnings("rawtypes") Class clazz, Object object)
128                    throws UnmarshallException {
129    
130                    JSONObject localeJSONObject = getLocaleJSONObject(object);
131    
132                    String country = null;
133    
134                    try {
135                            country = localeJSONObject.getString("country");
136                    }
137                    catch (Exception e) {
138                    }
139    
140                    String language = null;
141    
142                    try {
143                            language = localeJSONObject.getString("language");
144                    }
145                    catch (Exception e) {
146                            throw new UnmarshallException("language is undefined");
147                    }
148    
149                    String variant = null;
150    
151                    try {
152                            variant = localeJSONObject.getString("variant");
153                    }
154                    catch (Exception e) {
155                    }
156    
157                    Locale locale = null;
158    
159                    if (Validator.isNotNull(country) && Validator.isNotNull(language) &&
160                            Validator.isNotNull(variant)) {
161    
162                            locale = new Locale(language, country, variant);
163                    }
164                    else if (Validator.isNotNull(country) &&
165                                     Validator.isNotNull(language)) {
166    
167                            locale = new Locale(language, country);
168                    }
169                    else {
170                            locale = new Locale(language);
171                    }
172    
173                    serializerState.setSerialized(object, locale);
174    
175                    return locale;
176            }
177    
178            protected JSONObject getLocaleJSONObject(Object object)
179                    throws UnmarshallException {
180    
181                    JSONObject jsonObject = (JSONObject)object;
182    
183                    String javaClassName = null;
184    
185                    try {
186                            javaClassName = jsonObject.getString("javaClass");
187                    }
188                    catch (Exception e) {
189                            throw new UnmarshallException("Unable to get javaClass", e);
190                    }
191    
192                    if (javaClassName == null) {
193                            throw new UnmarshallException("javaClass is undefined");
194                    }
195    
196                    try {
197                            Class<?> javaClass = Class.forName(javaClassName);
198    
199                            Locale.class.isAssignableFrom(javaClass);
200                    }
201                    catch (Exception e) {
202                            throw new UnmarshallException(
203                                    "Unable to load javaClass " + javaClassName, e);
204                    }
205    
206                    JSONObject localeJSONObject = null;
207    
208                    try {
209                            localeJSONObject = jsonObject.getJSONObject("locale");
210                    }
211                    catch (Exception e) {
212                            throw new UnmarshallException("Unable to get locale", e);
213                    }
214    
215                    if (localeJSONObject == null) {
216                            throw new UnmarshallException("locale is undefined");
217                    }
218    
219                    return localeJSONObject;
220            }
221    
222            private static final Class<?>[] _JSON_CLASSES = {JSONObject.class};
223    
224            private static final Class<?>[] _SERIALIZABLE_CLASSES = {Locale.class};
225    
226    }