001    /*
002     * Copyright 2005-2007 The Kuali Foundation
003     *
004     *
005     * Licensed under the Educational Community License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     * http://www.opensource.org/licenses/ecl2.php
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.kuali.rice.core.resourceloader;
018    
019    import java.util.ArrayList;
020    import java.util.Iterator;
021    import java.util.List;
022    
023    import javax.xml.namespace.QName;
024    
025    import org.apache.commons.lang.ObjectUtils;
026    import org.apache.log4j.Logger;
027    import org.kuali.rice.core.lifecycle.BaseLifecycle;
028    import org.kuali.rice.core.reflect.ObjectDefinition;
029    import org.kuali.rice.core.resourceloader.ResourceLoader;
030    
031    /**
032     * A {@link ResourceLoader} which acts as a container for other ResourceLoaders.
033     * Effectively, implements a composite pattern for ResourceLoaders.
034     *
035     * @see ResourceLoader
036     *
037     * @author Kuali Rice Team (rice.collab@kuali.org)
038     */
039    public class ResourceLoaderContainer extends BaseLifecycle implements ResourceLoader {
040    
041            private static final Logger LOG = Logger.getLogger(ResourceLoaderContainer.class);
042    
043            private QName name;
044    
045            private List<ResourceLoader> resourceLoaders = new ArrayList<ResourceLoader>();
046    
047            public ResourceLoaderContainer(QName name) {
048                    this.name = name;
049            }
050    
051            public void start() throws Exception {
052                    for (ResourceLoader resourceLoader : this.resourceLoaders) {
053                            LOG.info("Starting ResourceLoader " + resourceLoader.getName());
054                            resourceLoader.start();
055                    }
056                    super.start();
057            }
058    
059            public void stop() throws Exception {
060                    while (!this.resourceLoaders.isEmpty()) {
061                            ResourceLoader rl = this.resourceLoaders.get(this.resourceLoaders.size() - 1);
062                            rl.stop();
063                            this.resourceLoaders.remove(rl);
064                    }
065    
066                    super.stop();
067                    this.resourceLoaders.clear();
068            }
069    
070            public void addResourceLoader(ResourceLoader resourceLoader) {
071                    this.resourceLoaders.add(resourceLoader);
072            }
073    
074            public void addResourceLoaderFirst(ResourceLoader resourceLoader) {
075                    this.resourceLoaders.add(0, resourceLoader);
076            }
077    
078            public boolean containsResourceLoader(ResourceLoader resourceLoader) {
079                    return this.resourceLoaders.contains(resourceLoader);
080            }
081    
082            public ResourceLoader getResourceLoader(QName name) {
083    
084                    if (this.getName().equals(name)) {
085                            return this;
086                    }
087    
088                    for (Iterator<ResourceLoader> iter = this.resourceLoaders.iterator(); iter.hasNext();) {
089                            ResourceLoader loader = iter.next();
090                            if (loader.getName().equals(name)) {
091                                    return loader;
092                            }
093                            ResourceLoader loader2 = loader.getResourceLoader(name);
094                            if (loader2 != null) {
095                                    return loader2;
096                            }
097                    }
098                    return null;
099            }
100    
101            public List<QName> getResourceLoaderNames() {
102                    List<QName> names = new ArrayList<QName>();
103                    for (Iterator<ResourceLoader> iter = this.resourceLoaders.iterator(); iter.hasNext();) {
104                            names.add(iter.next().getName());
105                    }
106                    return names;
107            }
108    
109            public void removeAllResourceLoaders() {
110                this.resourceLoaders.clear();
111            }
112    
113            public void removeResourceLoader(QName name) {
114                    ResourceLoader loaderToRemove = null;
115                    for (Iterator<ResourceLoader> iter = this.resourceLoaders.iterator(); iter.hasNext();) {
116                            ResourceLoader loader = iter.next();
117                            if (loader.getName().equals(name)) {
118                                    loaderToRemove = loader;
119                            }
120                    }
121                    if (loaderToRemove != null) {
122                            try {
123                                    loaderToRemove.stop();
124                            } catch (Exception e) {
125                                    LOG.error("Failed to stop plugin " + loaderToRemove.getName() + " on removal", e);
126                            }
127                            this.resourceLoaders.remove(loaderToRemove);
128                    }
129            }
130    
131            public List<ResourceLoader> getResourceLoaders() {
132                    return this.resourceLoaders;
133            }
134    
135    
136    
137            public Object getObject(ObjectDefinition definition) {
138                    for (ResourceLoader resourceLoader : this.resourceLoaders) {
139                            Object object = resourceLoader.getObject(definition);
140                            if (object != null) {
141                                    return object;
142                            }
143                    }
144                    return null;
145            }
146    
147            public Object getService(QName qname) {
148                    if (LOG.isDebugEnabled()) {
149                            LOG.debug("ResourceLoader " + getName() + " fetching service " + qname);
150                    }
151                    for (ResourceLoader resourceLoader : this.resourceLoaders) {
152                            if (LOG.isDebugEnabled()) {
153                                    LOG.debug("Delegating fetch to " + this);
154                            }
155                            Object service = resourceLoader.getService(qname);
156                            if (service != null) {
157                                    if (LOG.isDebugEnabled()) {
158                                            LOG.debug("Found service from " + this);
159                                    }
160                                    return service;
161                            }
162                    }
163                    return null;
164            }
165    
166            public String getContents(String indent, boolean servicePerLine) {
167                    String contents = indent + this + "\n";
168    
169                    for (ResourceLoader resourceLoader : this.resourceLoaders) {
170                            contents += resourceLoader.getContents(indent + "+++", servicePerLine);
171                    }
172    
173                    return contents;
174            }
175    
176            @Override
177            public String toString() {
178                    return "Resource Loader: " + this.name + " (" + ObjectUtils.identityToString(this) + ") direct children resource loaders size: " + this.resourceLoaders.size();
179            }
180    
181            public QName getName() {
182                    return this.name;
183            }
184    
185            public void setName(QName name) {
186                    this.name = name;
187            }
188    
189    
190    
191    
192    
193    }