001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.metamodel.facetapi;
021
022import java.util.ArrayList;
023import java.util.Hashtable;
024import java.util.List;
025import java.util.Map;
026
027import com.google.common.collect.Lists;
028
029import org.apache.isis.applib.filter.Filter;
030
031public final class FacetUtil {
032
033    private FacetUtil() {
034    }
035
036    /**
037     * Attaches the {@link Facet} to its {@link Facet#getFacetHolder() facet
038     * holder}.
039     * 
040     * @return <tt>true</tt> if a non-<tt>null</tt> facet was added,
041     *         <tt>false</tt> otherwise.
042     */
043    public static boolean addFacet(final Facet facet) {
044        if (facet == null) {
045            return false;
046        }
047        facet.getFacetHolder().addFacet(facet);
048        return true;
049    }
050
051    public static boolean addFacet(final MultiTypedFacet facet) {
052        if (facet == null) {
053            return false;
054        }
055        facet.getFacetHolder().addFacet(facet);
056        return true;
057    }
058
059    /**
060     * Attaches each {@link Facet} to its {@link Facet#getFacetHolder() facet
061     * holder}.
062     * 
063     * @return <tt>true</tt> if any facets were added, <tt>false</tt> otherwise.
064     */
065    public static boolean addFacets(final Facet[] facets) {
066        boolean addedFacets = false;
067        for (final Facet facet : facets) {
068            addedFacets = addFacet(facet) | addedFacets;
069        }
070        return addedFacets;
071    }
072
073    /**
074     * Attaches each {@link Facet} to its {@link Facet#getFacetHolder() facet
075     * holder}.
076     * 
077     * @return <tt>true</tt> if any facets were added, <tt>false</tt> otherwise.
078     */
079    public static boolean addFacets(final List<Facet> facetList) {
080        boolean addedFacets = false;
081        for (final Facet facet : facetList) {
082            addedFacets = addFacet(facet) | addedFacets;
083        }
084        return addedFacets;
085    }
086
087    /**
088     * Bit nasty, for use only by {@link FacetHolder}s that index their
089     * {@link Facet}s in a Map.
090     * 
091     * @param facetsByClass
092     * @return
093     */
094    @SuppressWarnings("unchecked")
095    public static Class<? extends Facet>[] getFacetTypes(final Map<Class<? extends Facet>, Facet> facetsByClass) {
096        return facetsByClass.keySet().toArray(new Class[0]);
097    }
098
099    /**
100     * Bit nasty, for use only by {@link FacetHolder}s that index their
101     * {@link Facet}s in a Map.
102     * 
103     * @param facetsByClass
104     * @return
105     */
106    public static List<Facet> getFacets(final Map<Class<? extends Facet>, Facet> facetsByClass, final Filter<Facet> filter) {
107        final List<Facet> filteredFacets = Lists.newArrayList();
108        final List<Facet> allFacets = new ArrayList<Facet>(facetsByClass.values());
109        for (int i = 0; i < allFacets.size(); i++) {
110            final Facet facet = allFacets.get(i);
111            if (filter.accept(facet)) {
112                filteredFacets.add(facet);
113            }
114        }
115        return filteredFacets;
116    }
117
118    public static void removeFacet(final Map<Class<? extends Facet>, Facet> facetsByClass, final Facet facet) {
119        removeFacet(facetsByClass, facet.facetType());
120    }
121
122    public static void removeFacet(final Map<Class<? extends Facet>, Facet> facetsByClass, final Class<? extends Facet> facetType) {
123        final Facet facet = facetsByClass.get(facetType);
124        if (facet == null) {
125            return;
126        }
127        facetsByClass.remove(facetType);
128        facet.setFacetHolder(null);
129    }
130
131    public static void addFacet(final Map<Class<? extends Facet>, Facet> facetsByClass, final Facet facet) {
132        facetsByClass.put(facet.facetType(), facet);
133    }
134
135    public static Facet[] toArray(final List<Facet> facetList) {
136        if (facetList == null) {
137            return new Facet[0];
138        } else {
139            return facetList.toArray(new Facet[] {});
140        }
141    }
142
143    public static Hashtable<Class<? extends Facet>, Facet> getFacetsByType(final FacetHolder facetHolder) {
144        final Hashtable<Class<? extends Facet>, Facet> facetByType = new Hashtable<Class<? extends Facet>, Facet>();
145        final Class<? extends Facet>[] facetsFor = facetHolder.getFacetTypes();
146        for (final Class<? extends Facet> facetType : facetsFor) {
147            final Facet facet = facetHolder.getFacet(facetType);
148            facetByType.put(facetType, facet);
149        }
150        return facetByType;
151    }
152
153    public static void copyFacets(final FacetHolder source, final FacetHolder target) {
154        List<Facet> facets = source.getFacets(org.apache.isis.applib.filter.Filters.<Facet>any());
155        for (Facet facet : facets) {
156            target.addFacet(facet);
157        }
158    }
159
160
161}