/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma; import java.util.List; import java.util.Locale; import java.util.NoSuchElementException; import javax.annotation.Nullable; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.ListMultimap; import com.google.common.collect.Multimaps; public abstract class AbstractAttributeAware implements AttributeAware { public abstract String getName(); @Override public boolean hasAttribute(String name) { return noNamespaceAttributes().containsKey(name); } @Override public boolean hasAttribute(String name, Locale locale) { if(noNamespaceAttributes().containsKey(name)) { for(Attribute attribute : noNamespaceAttributes().get(name)) { if(attribute.isLocalised() && attribute.getLocale().equals(locale)) { return true; } } } return false; } @Override public boolean hasAttribute(String namespace, String name) { ListMultimap<String, Attribute> nm = namespaceAttributes(namespace); return name == null || nm.containsKey(name); } @Override public boolean hasAttribute(String namespace, String name, Locale locale) { for(Attribute attribute : namespaceAttributes(namespace).get(name)) { if(attribute.isLocalised() && attribute.getLocale().equals(locale)) { return true; } } return false; } @Override public Attribute getAttribute(String name) { try { return Iterables.get(noNamespaceAttributes().get(name), 0); } catch(IndexOutOfBoundsException e) { throw new NoSuchAttributeException(name, getName()); } } @Override public Attribute getAttribute(String name, final Locale locale) { try { return Iterables.find(noNamespaceAttributes().get(name), new Predicate<Attribute>() { @Override public boolean apply(Attribute input) { return input.isLocalised() && input.getLocale().equals(locale); } }); } catch(NoSuchElementException e) { throw new NoSuchAttributeException(name, locale, getName()); } } @Override public Attribute getAttribute(String namespace, String name) throws NoSuchAttributeException { try { return Iterables.get(namespaceAttributes(namespace).get(name), 0); } catch(IndexOutOfBoundsException e) { throw new NoSuchAttributeException(namespace + "::" + name, getName()); } } @Override public Attribute getAttribute(String namespace, String name, final Locale locale) throws NoSuchAttributeException { try { return Iterables.find(namespaceAttributes(namespace).get(name), new Predicate<Attribute>() { @Override public boolean apply(Attribute input) { return input.isLocalised() && input.getLocale().equals(locale); } }); } catch(NoSuchElementException e) { throw new NoSuchAttributeException(name, locale, getName()); } } @Override public List<Attribute> getAttributes(String namespace, String name) throws NoSuchAttributeException { return ImmutableList.copyOf(namespaceAttributes(namespace).get(name)); } @Override public List<Attribute> getNamespaceAttributes(String namespace) throws NoSuchAttributeException { return ImmutableList.copyOf(namespaceAttributes(namespace).values()); } @Override public Value getAttributeValue(String name) throws NoSuchAttributeException { return getAttribute(name).getValue(); } @Override public Value getAttributeValue(String namespace, String name) throws NoSuchAttributeException { return getAttribute(namespace, name).getValue(); } @Override public String getAttributeStringValue(String name) throws NoSuchAttributeException { return getAttribute(name).getValue().toString(); } @Override public String getAttributeStringValue(String namespace, String name) throws NoSuchAttributeException { return getAttribute(namespace, name).getValue().toString(); } @Override public List<Attribute> getAttributes(String name) throws NoSuchAttributeException { if(!hasAttribute(name)) throw new NoSuchAttributeException(name, getName()); return ImmutableList.copyOf(noNamespaceAttributes().get(name)); } @Override public List<Attribute> getAttributes() { return ImmutableList.copyOf(getInstanceAttributes().values()); } @Override public boolean hasAttributes() { return getInstanceAttributes().size() > 0; } protected abstract ListMultimap<String, Attribute> getInstanceAttributes(); protected ListMultimap<String, Attribute> noNamespaceAttributes() { return namespaceAttributes(null); } /** * Returns a view of the attributes for the specified namespace. If namespace is null, this method returns attributes * that have no namespace (namespace is null). */ protected ListMultimap<String, Attribute> namespaceAttributes(@Nullable final String namespace) { return Multimaps.index(Iterables.filter(getInstanceAttributes().values(), new Predicate<Attribute>() { @Override public boolean apply(Attribute input) { // Allows namespace to be null return Objects.equal(namespace, input.hasNamespace() ? input.getNamespace() : null); } }), AttributeNameFunc.INSTANCE); } private static final class AttributeNameFunc implements Function<Attribute, String> { @SuppressWarnings("TypeMayBeWeakened") private static final AttributeNameFunc INSTANCE = new AttributeNameFunc(); @Override public String apply(Attribute input) { return input == null ? null : input.getName(); } } }