Package org.jboss.gravia.resource.spi

Source Code of org.jboss.gravia.resource.spi.AttributeValueHandler$AttributeValue

/*
* #%L
* Gravia :: Resource
* %%
* Copyright (C) 2010 - 2014 JBoss by Red Hat
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package org.jboss.gravia.resource.spi;

import static org.jboss.gravia.resource.ContentNamespace.CAPABILITY_MAVEN_IDENTITY_ATTRIBUTE;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.jboss.gravia.resource.MavenCoordinates;
import org.jboss.gravia.resource.Version;
import org.jboss.gravia.resource.VersionRange;

/**
* A handler for attribute values.
*
* @author thomas.diesler@jboss.com
* @since 06-Jul-2012
*/
public final class AttributeValueHandler {

    public static enum Type {
        Boolean,
        Double,
        Float,
        Integer,
        Long,
        Maven,
        String,
        URL,
        Version,
        VersionRange
    }

    /**
     * Read attribute values according to
     * 132.5.6 Attribute Element
     */
    public static AttributeValue readAttributeValue(String typespec, String valstr) {
        return readAttributeValue(null,  typespec, valstr);
    }

    public static AttributeValue readAttributeValue(String keystr, String typespec, String valstr) {
        boolean listType = false;
        if (typespec != null && typespec.startsWith("List<") && typespec.endsWith(">")) {
            typespec = typespec.substring(5, typespec.length() - 1);
            listType = true;
        }

        Type type;
        if (typespec != null) {
            type = Type.valueOf(typespec);
        } else if (CAPABILITY_MAVEN_IDENTITY_ATTRIBUTE.equals(keystr)) {
            type = Type.Maven;
        } else {
            type = Type.String;
        }

        // Whitespace around the list and around commas must be trimmed
        valstr = valstr.trim();

        Object value;
        switch (type) {
            case Boolean:
                if (listType) {
                    List<Boolean> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(Boolean.parseBoolean(val.trim()));
                    }
                    value = list;
                } else {
                    value = Boolean.parseBoolean(valstr);
                }
                break;
            case Double:
                if (listType) {
                    List<Double> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(Double.parseDouble(val.trim()));
                    }
                    value = list;
                } else {
                    value = Double.parseDouble(valstr);
                }
                break;
            case Float:
                if (listType) {
                    List<Float> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(Float.parseFloat(val.trim()));
                    }
                    value = list;
                } else {
                    value = Float.parseFloat(valstr);
                }
                break;
            case Integer:
                if (listType) {
                    List<Integer> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(Integer.parseInt(val.trim()));
                    }
                    value = list;
                } else {
                    value = Integer.parseInt(valstr);
                }
                break;
            case Long:
                if (listType) {
                    List<Long> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(Long.parseLong(val.trim()));
                    }
                    value = list;
                } else {
                    value = Long.parseLong(valstr);
                }
                break;
            case Maven:
                if (listType) {
                    List<MavenCoordinates> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(MavenCoordinates.parse(val.trim()));
                    }
                    value = list;
                } else {
                    value = MavenCoordinates.parse(valstr);
                }
                break;
            case String:
                if (listType) {
                    List<String> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(val.trim());
                    }
                    value = list;
                } else {
                    value = valstr;
                }
                break;
            case URL:
                if (listType) {
                    List<URL> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(toURL(val.trim()));
                    }
                    value = list;
                } else {
                    value = toURL(valstr);
                }
                break;
            case Version:
                if (listType) {
                    List<Version> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(Version.parseVersion(val.trim()));
                    }
                    value = list;
                } else {
                    value = Version.parseVersion(valstr);
                }
                break;
            case VersionRange:
                if (listType) {
                    List<VersionRange> list = new ArrayList<>();
                    for (String val : split(valstr)) {
                        list.add(new VersionRange(val.trim()));
                    }
                    value = list;
                } else {
                    value = new VersionRange(valstr);
                }
                break;
            default:
                value = valstr;
                break;
        }
        return new AttributeValue(type, value);
    }

    private static URL toURL(String urlspec) {
        try {
            return new URL(urlspec);
        } catch (MalformedURLException ex) {
            throw new IllegalArgumentException(ex);
        }
    }

    private static List<String> split(String valstr) {
        boolean escape = false;
        StringBuffer tok = new StringBuffer();
        List<String> result = new ArrayList<String>();

        for (int i = 0; i < valstr.length(); i++) {
            char ch = valstr.charAt(i);
            if (ch == '\\' && !escape) {
                escape = true;
                continue;
            }
            if (escape && ch != '\\' && ch != ',' && ch != '"') {
                tok.append('\\');
                escape = false;
            }
            if (ch == ',' && !escape) {
                result.add(tok.toString());
                tok = new StringBuffer();
                escape = false;
                continue;
            }
            tok.append(ch);
            escape = false;
        }
        if (tok.length() > 0) {
            result.add(tok.toString());
        }
        return result;
    }

    public static class AttributeValue {
        private final Type type;
        private final Object value;
        private final boolean listType;

        public static AttributeValue parse(String external) {
            String typespec = external.substring(external.indexOf("type=") + 5, external.indexOf(','));
            String valuestr = external.substring(external.indexOf("value=") + 6, external.length() - 1);
            return AttributeValueHandler.readAttributeValue(typespec, valuestr);
        }

        public static AttributeValue create(Object value) {
            Class<?> valueType = value.getClass();
            boolean listType = List.class.isAssignableFrom(valueType);
            if (listType) {
                List<?> list = (List<?>) value;
                if (!list.isEmpty()) {
                    // Use the type of the first element in the list
                    valueType = list.get(0).getClass();
                } else {
                    // For an empty list it is not possible to infer it's component type
                    valueType = String.class;
                }
            }
            Type type;
            if (MavenCoordinates.class == valueType) {
                type = Type.Maven;
            } else {
                String simpleName = valueType.getSimpleName();
                type = Type.valueOf(simpleName);
            }
            return new AttributeValue(type, value);
        }

        private AttributeValue(Type type, Object value) {
            assert type != null : "Null type";
            assert value != null : "Null value";
            this.type = type;
            this.value = value;
            Class<? extends Object> valueClass = value.getClass();
            this.listType = List.class.isAssignableFrom(valueClass);
        }

        public Type getType() {
            return type;
        }

        public Object getValue() {
            return value;
        }

        public String getValueString() {
            StringBuffer result = new StringBuffer();
            if (listType) {
                for (Object val : (List<?>) value) {
                    if (result.length() > 0) {
                        result.append(", ");
                    }
                    result.append(escape(val));
                }
            } else {
                result.append(value);
            }
            return result.toString();
        }

        private String escape(Object val) {
            String valstr = val.toString();
            if (type != Type.String)
                return valstr;

            StringBuffer result = new StringBuffer();
            for (int i = 0; i < valstr.length(); i++) {
                char ch = valstr.charAt(i);
                if (ch == '\\' || ch == ',' || ch == '"') {
                    result.append("\\" + ch);
                } else {
                    result.append(ch);
                }
            }
            return result.toString();
        }

        public boolean isListType() {
            return listType;
        }

        public String toExternalForm() {
            String typespec = listType ? "List<" + type + ">" : "" + type;
            String valstr = value.toString();
            if (listType) {
                valstr = valstr.substring(1, valstr.length() -1);
            }
            return "[type=" + typespec + ", value=" + valstr + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((type == null) ? 0 : type.hashCode());
            result = prime * result + ((value == null) ? 0 : value.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (!(obj instanceof AttributeValue)) return false;
            AttributeValue other = (AttributeValue) obj;
            return type.equals(other.type) && value.equals(other.value);
        }

        @Override
        public String toString() {
            return toExternalForm();
        }
    }
}
TOP

Related Classes of org.jboss.gravia.resource.spi.AttributeValueHandler$AttributeValue

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.