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