Java tutorial
/** * 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(); } }