001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
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.apache.geronimo.system.plugin;
018    
019    import java.io.BufferedReader;
020    import java.io.File;
021    import java.io.IOException;
022    import java.io.InputStreamReader;
023    import java.net.MalformedURLException;
024    import java.net.URI;
025    import java.net.URL;
026    import java.net.URISyntaxException;
027    import java.util.ArrayList;
028    import java.util.List;
029    
030    import org.apache.commons.logging.Log;
031    import org.apache.commons.logging.LogFactory;
032    import org.apache.geronimo.gbean.AbstractName;
033    import org.apache.geronimo.gbean.GBeanInfo;
034    import org.apache.geronimo.gbean.GBeanInfoBuilder;
035    import org.apache.geronimo.kernel.Kernel;
036    
037    /**
038     * An implementation of PluginRepositoryList that downloads plugins from
039     * an Apache web site.
040     *
041     * @version $Rev: 557828 $ $Date: 2007-07-19 20:51:24 -0400 (Thu, 19 Jul 2007) $
042     */
043    public class PluginRepositoryDownloader implements PluginRepositoryList {
044        private final static Log log = LogFactory.getLog(PluginRepositoryDownloader.class);
045        private List<String> downloadRepositories = new ArrayList<String>();
046        private List<String> userRepositories = new ArrayList<String>();
047        private Kernel kernel;
048        private AbstractName name;
049        private URL repositoryList;
050    
051        public PluginRepositoryDownloader(List<String> downloadRepositories, List<String> userRepositories, URL repositoryList, Kernel kernel, AbstractName name) {
052            if (downloadRepositories != null) this.downloadRepositories = downloadRepositories;
053            if (userRepositories != null) this.userRepositories = userRepositories;
054            this.repositoryList = repositoryList;
055            this.kernel = kernel;
056            this.name = name;
057        }
058    
059        /**
060         * The list of repositories that were downloaded from central.
061         */
062        public void setDownloadRepositories(List<String> downloadRepositories) {
063            this.downloadRepositories = downloadRepositories;
064            if (this.downloadRepositories == null) this.downloadRepositories = new ArrayList<String>();
065        }
066    
067        /**
068         * Any repositories that the user added manually
069         */
070        public void setUserRepositories(List<String> userRepositories) {
071            this.userRepositories = userRepositories;
072            if (this.userRepositories == null) this.userRepositories = new ArrayList<String>();
073        }
074    
075        /**
076         * Gets the union of centrally-listed repositories and user-added repositories.
077         */
078        public URL[] getRepositories() {
079            List<URL> list = new ArrayList<URL>();
080            for (String url : downloadRepositories) {
081                try {
082                    list.add(new URL(url.trim()));
083                } catch (MalformedURLException e) {
084                    log.error("Unable to format plugin repository URL " + url, e);
085                }
086            }
087            for (String userRepository : userRepositories) {
088                userRepository = userRepository.trim();
089                try {
090                    URI uri = new URI(userRepository);
091                    if (uri.getScheme() == null) {
092                        if (uri.isAbsolute()) {
093                            URL url = new URI("file", userRepository, null).toURL();
094                            list.add(url);
095                        } else if (userRepository.startsWith("~")) {
096                            userRepository = userRepository.substring(2);
097                            URI fullUri = new URI("file", System.getProperty("user.home") + "/", null).resolve(userRepository);
098                            list.add(fullUri.toURL());
099                        } else {
100                            log.error("Can't interpret path: " + userRepository);
101                        }
102                    } else {
103                        list.add(uri.toURL());
104                    }
105                } catch (MalformedURLException e) {
106                    log.error("Unable to format plugin repository URL " + userRepository, e);
107                } catch (URISyntaxException e) {
108                    log.error("Unable to format plugin repository URL " + userRepository, e);
109                }
110            }
111            return list.toArray(new URL[list.size()]);
112        }
113    
114        /**
115         * Go download a fresh copy of the repository list.
116         */
117        public void refresh() {
118            BufferedReader in = null;
119            try {
120                in = new BufferedReader(new InputStreamReader(repositoryList.openStream()));
121                String line;
122                List<String> list = new ArrayList<String>();
123                while ((line = in.readLine()) != null) {
124                    line = line.trim();
125                    if (!line.equals("") && !line.startsWith("#")) {
126                        list.add(line);
127                    }
128                }
129                in.close();
130                in = null;
131                //this saves the new value in config.xml
132                kernel.setAttribute(name, "downloadRepositories", list);
133            } catch (Exception e) {
134                log.error("Unable to save download repositories", e);
135            } finally {
136                if (in != null) {
137                    try {
138                        in.close();
139                    } catch (IOException ignored) {
140                    }
141                }
142            }
143        }
144    
145        /**
146         * Adds a new repository that the user put in manually.
147         */
148        public void addUserRepository(URL repo) {
149            userRepositories.add(repo.toString());
150            try {
151                kernel.setAttribute(name, "userRepositories", userRepositories);
152            } catch (Exception e) {
153                log.error("Unable to save user repositories", e);
154            }
155        }
156    
157        public static final GBeanInfo GBEAN_INFO;
158    
159        static {
160            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(PluginRepositoryDownloader.class);
161    
162            infoFactory.addAttribute("downloadRepositories", List.class, true);
163            infoFactory.addAttribute("userRepositories", List.class, true);
164            infoFactory.addAttribute("repositoryList", URL.class, true);
165            infoFactory.addAttribute("kernel", Kernel.class, false);
166            infoFactory.addAttribute("abstractName", AbstractName.class, false);
167            infoFactory.addInterface(PluginRepositoryList.class);
168            infoFactory.setConstructor(new String[]{"downloadRepositories", "userRepositories", "repositoryList", "kernel", "abstractName"});
169    
170            GBEAN_INFO = infoFactory.getBeanInfo();
171        }
172    
173        public static GBeanInfo getGBeanInfo() {
174            return GBEAN_INFO;
175        }
176    }