com.zauberlabs.commons.mom.internal.AttributesMap.java Source code

Java tutorial

Introduction

Here is the source code for com.zauberlabs.commons.mom.internal.AttributesMap.java

Source

/**
 * Copyright (c) 2009-2012 Zauber S.A. <http://www.zaubersoftware.com/>
 *
 * 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.
 */
package com.zauberlabs.commons.mom.internal;

import static net.sf.staccatocommons.lang.tuple.Tuples.*;

import java.lang.reflect.Method;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.staccatocommons.collections.stream.Streams;
import net.sf.staccatocommons.lang.function.AbstractFunction;
import net.sf.staccatocommons.restrictions.check.NonNull;

import org.apache.commons.lang.StringUtils;

import com.zauberlabs.commons.mom.MapObjectMapper;
import com.zauberlabs.commons.mom.NaiveProperties;

/**
 * A delayed map that projects an object into a map. The logic is the following:
 * Null attributes are converted into null, mappeable arrays object attributes
 * are converted into collections of maps, mappeable object attributes are
 * converted into maps, and any other attribute is left unchanged.
 */
@SuppressWarnings("unchecked")
public class AttributesMap extends AbstractMap<String, Object> {
    private final MapObjectMapper mom;
    private final Object target;
    private static final Pattern GETTER_PATTERN = Pattern.compile("(is|get)([A-Z].*)");

    /**
     * Creates the {@link AttributesMap}
     *
     * @param object
     * @param mom
     */
    public AttributesMap(final Object object, @NonNull final MapObjectMapper mom) {
        this.target = object;
        this.mom = mom;
    }

    @Override
    public final Object get(final Object name) {
        return name.equals("class") ? null : transform(NaiveProperties.get(target, (String) name));
    }

    @Override
    public final boolean containsKey(final Object name) {
        return !"class".equals(name) && super.containsKey(name);
    }

    /**
     * Transforms the given map value into a mapped object in SLM format
     */
    protected Object transform(final Object value) {
        return mom.map(value);
    }

    @Override
    public Set<Entry<String, Object>> entrySet() {
        return Streams.cons(target.getClass().getMethods()).filter(NaiveProperties.argCount(0))
                .flatMap(new AbstractFunction.Soft<Method, Iterable<? extends Entry<String, Object>>>() {
                    @Override
                    public Iterable<? extends java.util.Map.Entry<String, Object>> softApply(final Method arg)
                            throws Exception {
                        if (arg.getName().equals("getClass")) {
                            return Collections.emptyList();
                        }

                        Matcher m = GETTER_PATTERN.matcher(arg.getName());
                        if (!m.find()) {
                            return Collections.emptyList();
                        }
                        return Arrays
                                .asList(_(StringUtils.uncapitalize(m.group(2)), transform(arg.invoke(target))));
                    }
                }).toSet();
    }

}