001    /*
002     * JBoss, Home of Professional Open Source.
003     * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004     * as indicated by the @author tags. See the copyright.txt file in the
005     * distribution for a full listing of individual contributors. 
006     *
007     * This is free software; you can redistribute it and/or modify it
008     * under the terms of the GNU Lesser General Public License as
009     * published by the Free Software Foundation; either version 2.1 of
010     * the License, or (at your option) any later version.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this software; if not, write to the Free
019     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021     */
022    package org.jboss.dna.connector.federation;
023    
024    import java.util.ArrayList;
025    import java.util.Collections;
026    import java.util.Iterator;
027    import java.util.List;
028    import net.jcip.annotations.Immutable;
029    import org.jboss.dna.common.collection.Problems;
030    import org.jboss.dna.common.collection.ThreadSafeProblems;
031    import org.jboss.dna.common.util.CheckArg;
032    import org.jboss.dna.graph.cache.CachePolicy;
033    import org.jboss.dna.graph.connectors.RepositorySource;
034    
035    /**
036     * The configuration of a federated repository. The configuration defines, among other things, the set of
037     * {@link #getSourceProjections() source projections} in the federated repository that each specify how and where content from a
038     * {@link RepositorySource source} is federated into the unified repository.
039     * 
040     * @author Randall Hauch
041     */
042    @Immutable
043    public class FederatedRepositoryConfig implements Comparable<FederatedRepositoryConfig> {
044    
045        private final Projection cacheProjection;
046        private final List<Projection> sourceProjections;
047        private final Problems problems;
048        private final String name;
049        private final CachePolicy defaultCachePolicy;
050    
051        /**
052         * Create a federated repository instance.
053         * 
054         * @param repositoryName the name of the repository
055         * @param cacheProjection the projection used for the cache; may not be null
056         * @param sourceProjections the source projections; may not be null
057         * @param defaultCachePolicy the default cache policy for this repository; may be null
058         * @throws IllegalArgumentException if the name is null or is blank
059         */
060        public FederatedRepositoryConfig( String repositoryName,
061                                          Projection cacheProjection,
062                                          Iterable<Projection> sourceProjections,
063                                          CachePolicy defaultCachePolicy ) {
064            CheckArg.isNotEmpty(repositoryName, "repositoryName");
065            CheckArg.isNotNull(cacheProjection, "cacheProjection");
066            this.name = repositoryName;
067            this.problems = new ThreadSafeProblems();
068            this.defaultCachePolicy = defaultCachePolicy;
069            this.cacheProjection = cacheProjection;
070            List<Projection> projectionList = new ArrayList<Projection>();
071            for (Projection projection : sourceProjections) {
072                if (projection == null) continue;
073                if (!projectionList.contains(projection)) {
074                    projectionList.add(projection);
075                }
076            }
077            this.sourceProjections = Collections.unmodifiableList(projectionList);
078            CheckArg.isNotEmpty(this.sourceProjections, "sourceProjections");
079        }
080    
081        /**
082         * Get the name of this repository
083         * 
084         * @return name
085         */
086        public String getName() {
087            return this.name;
088        }
089    
090        /**
091         * Return the problem associated with this configuration. These problems may change at any time, although the returned
092         * {@link Problems} object is thread-safe.
093         * 
094         * @return the thread-safe problems for this configuration
095         */
096        public Problems getProblems() {
097            return problems;
098        }
099    
100        /**
101         * Get the projection that defines the cache for this repository. This projection does not exist in the
102         * {@link #getSourceProjections() list of source projections}.
103         * 
104         * @return the region used for caching; never null
105         */
106        public Projection getCacheProjection() {
107            return cacheProjection;
108        }
109    
110        /**
111         * Return the unmodifiable list of source projections.
112         * 
113         * @return the source projections; never null and never empty
114         */
115        public List<Projection> getSourceProjections() {
116            return sourceProjections;
117        }
118    
119        /**
120         * Get the default cache policy for the repository with the supplied name
121         * 
122         * @return the default cache policy
123         */
124        public CachePolicy getDefaultCachePolicy() {
125            return defaultCachePolicy;
126        }
127    
128        /**
129         * {@inheritDoc}
130         * 
131         * @see java.lang.Object#hashCode()
132         */
133        @Override
134        public int hashCode() {
135            return this.name.hashCode();
136        }
137    
138        /**
139         * {@inheritDoc}
140         * 
141         * @see java.lang.Object#equals(java.lang.Object)
142         */
143        @Override
144        public boolean equals( Object obj ) {
145            if (obj == this) return true;
146            if (obj instanceof FederatedRepositoryConfig) {
147                FederatedRepositoryConfig that = (FederatedRepositoryConfig)obj;
148                if (!this.getName().equals(that.getName())) return false;
149                if (!this.getCacheProjection().equals(that.getCacheProjection())) return false;
150                if (!this.getSourceProjections().equals(that.getSourceProjections())) return false;
151                return true;
152            }
153            return false;
154        }
155    
156        /**
157         * {@inheritDoc}
158         * 
159         * @see java.lang.Comparable#compareTo(java.lang.Object)
160         */
161        public int compareTo( FederatedRepositoryConfig that ) {
162            if (that == this) return 0;
163            int diff = this.getName().compareTo(that.getName());
164            if (diff != 0) return diff;
165            diff = this.getCacheProjection().compareTo(that.getCacheProjection());
166            if (diff != 0) return diff;
167            Iterator<Projection> thisIter = this.getSourceProjections().iterator();
168            Iterator<Projection> thatIter = that.getSourceProjections().iterator();
169            while (thisIter.hasNext() && thatIter.hasNext()) {
170                diff = thisIter.next().compareTo(thatIter.next());
171                if (diff != 0) return diff;
172            }
173            if (thisIter.hasNext()) return 1;
174            if (thatIter.hasNext()) return -1;
175            return 0;
176        }
177    }