001    /**
002     * Copyright (c) 2000-2012 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            public Class<?>[] getJSONClasses() {
049                    return _JSON_CLASSES;
050            }
051    
052            public Class<?>[] getSerializableClasses() {
053                    return _SERIALIZABLE_CLASSES;
054            }
055    
056            public Object marshall(
057                            SerializerState serializerState, Object parentObject, Object object)
058                    throws MarshallException {
059    
060                    JSONObject jsonObject = new JSONObject();
061    
062                    if (ser.getMarshallClassHints()) {
063                            try {
064                                    Class<?> javaClass = object.getClass();
065    
066                                    jsonObject.put("javaClass", javaClass.getName());
067                            }
068                            catch (Exception e) {
069                                    throw new MarshallException("Unable to put javaClass", e);
070                            }
071                    }
072    
073                    JSONObject localeJSONObject = new JSONObject();
074    
075                    try {
076                            jsonObject.put("locale", localeJSONObject);
077    
078                            serializerState.push(object, localeJSONObject, "locale");
079                    }
080                    catch (Exception e) {
081                            throw new MarshallException("Unable to put locale", e);
082                    }
083    
084                    try {
085                            Locale locale = (Locale)object;
086    
087                            localeJSONObject.put("country", locale.getCountry());
088                            localeJSONObject.put("language", locale.getLanguage());
089                            localeJSONObject.put("variant", locale.getVariant());
090                    }
091                    catch (Exception e) {
092                            throw new MarshallException(
093                                    "Unable to put country, language, and variant", e);
094                    }
095                    finally {
096                            serializerState.pop();
097                    }
098    
099                    return jsonObject;
100            }
101    
102            public ObjectMatch tryUnmarshall(
103                            SerializerState serializerState,
104                            @SuppressWarnings("rawtypes") Class clazz, Object object)
105                    throws UnmarshallException {
106    
107                    JSONObject localeJSONObject = getLocaleJSONObject(object);
108    
109                    ObjectMatch objectMatch = ObjectMatch.ROUGHLY_SIMILAR;
110    
111                    if (localeJSONObject.has("language")) {
112                            objectMatch = ObjectMatch.OKAY;
113                    }
114    
115                    serializerState.setSerialized(object, objectMatch);
116    
117                    return objectMatch;
118            }
119    
120            public Object unmarshall(
121                            SerializerState serializerState,
122                            @SuppressWarnings("rawtypes") Class clazz, Object object)
123                    throws UnmarshallException {
124    
125                    JSONObject localeJSONObject = getLocaleJSONObject(object);
126    
127                    String country = null;
128    
129                    try {
130                            country = localeJSONObject.getString("country");
131                    }
132                    catch (Exception e) {
133                    }
134    
135                    String language = null;
136    
137                    try {
138                            language = localeJSONObject.getString("language");
139                    }
140                    catch (Exception e) {
141                            throw new UnmarshallException("language is undefined");
142                    }
143    
144                    String variant = null;
145    
146                    try {
147                            variant = localeJSONObject.getString("variant");
148                    }
149                    catch (Exception e) {
150                    }
151    
152                    Locale locale = null;
153    
154                    if (Validator.isNotNull(country) && Validator.isNotNull(language) &&
155                            Validator.isNotNull(variant)) {
156    
157                            locale = new Locale(language, country, variant);
158                    }
159                    else if (Validator.isNotNull(country) &&
160                                     Validator.isNotNull(language)) {
161    
162                            locale = new Locale(language, country);
163                    }
164                    else {
165                            locale = new Locale(language);
166                    }
167    
168                    serializerState.setSerialized(object, locale);
169    
170                    return locale;
171            }
172    
173            protected JSONObject getLocaleJSONObject(Object object)
174                    throws UnmarshallException {
175    
176                    JSONObject jsonObject = (JSONObject)object;
177    
178                    String javaClassName = null;
179    
180                    try {
181                            javaClassName = jsonObject.getString("javaClass");
182                    }
183                    catch (Exception e) {
184                            throw new UnmarshallException("Unable to get javaClass", e);
185                    }
186    
187                    if (javaClassName == null) {
188                            throw new UnmarshallException("javaClass is undefined");
189                    }
190    
191                    try {
192                            Class<?> javaClass = Class.forName(javaClassName);
193    
194                            Locale.class.isAssignableFrom(javaClass);
195                    }
196                    catch (Exception e) {
197                            throw new UnmarshallException(
198                                    "Unable to load javaClass " + javaClassName, e);
199                    }
200    
201                    JSONObject localeJSONObject = null;
202    
203                    try {
204                            localeJSONObject = jsonObject.getJSONObject("locale");
205                    }
206                    catch (Exception e) {
207                            throw new UnmarshallException("Unable to get locale", e);
208                    }
209    
210                    if (localeJSONObject == null) {
211                            throw new UnmarshallException("locale is undefined");
212                    }
213    
214                    return localeJSONObject;
215            }
216    
217            private static final Class<?>[] _JSON_CLASSES = {JSONObject.class};
218    
219            private static final Class<?>[] _SERIALIZABLE_CLASSES = {Locale.class};
220    
221    }