001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others.
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 * Contributors:
017 *     Nicolas Chapurlat
018 */
019package org.nuxeo.ecm.core.schema.types.resolver;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.Collections;
024import java.util.HashMap;
025import java.util.List;
026import java.util.Locale;
027import java.util.Map;
028
029public class TestingColorResolver implements ObjectResolver {
030
031    public static enum MODE {
032        PRIMARY, SECONDARY;
033    }
034
035    public interface Color {
036        String name();
037    }
038
039    public static enum PrimaryColor implements Color {
040        RED, BLUE, YELLOW;
041    }
042
043    public static enum SecondaryColor implements Color {
044        VIOLET, ORANGE, GREEN;
045    }
046
047    public static final String COLOR_MODE = "mode";
048
049    public static final String NAME = "colorReference";
050
051    private MODE mode;
052
053    private Map<String, Serializable> parameters;
054
055    private List<Class<?>> managedClasses = null;
056
057    @Override
058    public List<Class<?>> getManagedClasses() {
059        if (managedClasses == null) {
060            managedClasses = new ArrayList<Class<?>>();
061            managedClasses.add(Color.class);
062        }
063        return managedClasses;
064    }
065
066    @Override
067    public void configure(Map<String, String> parameters) throws IllegalStateException, IllegalArgumentException {
068        if (this.parameters != null) {
069            throw new IllegalStateException("cannot change configuration, may be already in use somewhere");
070        }
071        String modeParam = parameters.get(COLOR_MODE);
072        if (modeParam == null || modeParam.trim().isEmpty()) {
073            throw new IllegalArgumentException("missing mode param");
074        }
075        try {
076            mode = MODE.valueOf(modeParam);
077        } catch (IllegalArgumentException e) {
078            throw new IllegalArgumentException("missing mode param", e);
079        }
080        this.parameters = new HashMap<String, Serializable>();
081        this.parameters.put(COLOR_MODE, mode.name());
082    }
083
084    @Override
085    public String getName() throws IllegalStateException {
086        checkConfig();
087        return NAME;
088    }
089
090    @Override
091    public Map<String, Serializable> getParameters() throws IllegalStateException {
092        checkConfig();
093        return Collections.unmodifiableMap(parameters);
094    }
095
096    @Override
097    public boolean validate(Object value) throws IllegalStateException {
098        checkConfig();
099        return fetch(value) != null;
100    }
101
102    @Override
103    public Color fetch(Object value) throws IllegalStateException {
104        checkConfig();
105        if (value instanceof String) {
106            String ref = (String) value;
107            switch (mode) {
108            case PRIMARY:
109                for (PrimaryColor color : PrimaryColor.values()) {
110                    if (color.name().equals(ref)) {
111                        return color;
112                    }
113                }
114                break;
115            case SECONDARY:
116                for (SecondaryColor color : SecondaryColor.values()) {
117                    if (color.name().equals(ref)) {
118                        return color;
119                    }
120                }
121                break;
122            }
123        }
124        return null;
125    }
126
127    @Override
128    @SuppressWarnings("unchecked")
129    public <T> T fetch(Class<T> type, Object value) throws IllegalStateException {
130        checkConfig();
131        if (Color.class.equals(type)) {
132            return (T) fetch(value);
133        } else if (mode == MODE.PRIMARY && PrimaryColor.class.equals(type)) {
134            return (T) fetch(value);
135        } else if (mode == MODE.SECONDARY && SecondaryColor.class.equals(type)) {
136            return (T) fetch(value);
137        }
138        return null;
139    }
140
141    @Override
142    public Serializable getReference(Object entity) throws IllegalStateException {
143        checkConfig();
144        if (entity instanceof Color) {
145            Color color = (Color) entity;
146            if (color != null) {
147                switch (mode) {
148                case PRIMARY:
149                    if (color instanceof PrimaryColor) {
150                        return color.name();
151                    }
152                    break;
153                case SECONDARY:
154                    if (color instanceof SecondaryColor) {
155                        return color.name();
156                    }
157                    break;
158                }
159            }
160        }
161        return null;
162    }
163
164    @Override
165    public String getConstraintErrorMessage(Object invalidValue, Locale locale) {
166        checkConfig();
167        return String.format("\"%s\" is not a correct %s color", invalidValue, mode.name().toLowerCase());
168    }
169
170    private void checkConfig() throws IllegalStateException {
171        if (parameters == null) {
172            throw new IllegalStateException(
173                    "you should call #configure(Map<String, String>) before. Please get this resolver throught ExternalReferenceService which is in charge of resolver configuration.");
174        }
175    }
176
177}