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 */
019package org.apache.wiki.modules;
020
021import java.io.BufferedInputStream;
022import java.io.ByteArrayOutputStream;
023import java.io.IOException;
024import java.net.URL;
025
026import org.jdom2.Element;
027
028import org.apache.wiki.util.FileUtil;
029
030/**
031 *  A WikiModule describes whatever JSPWiki plugin there is: it can be a plugin,
032 *  an editor, a filter, etc.
033 *
034 *  @since 2.4
035 */
036public class WikiModuleInfo
037    implements Comparable<WikiModuleInfo>
038{
039    protected String m_name;
040    protected String m_description;
041    protected String m_moduleUrl;
042    protected String m_moduleVersion;
043    protected String m_htmlTemplate;
044    protected String m_scriptLocation;
045    protected String m_scriptText;
046    protected String m_stylesheetLocation;
047    protected String m_stylesheetText;
048    protected String m_author;
049    protected String m_authorUrl;
050    protected URL    m_resource;
051    protected String m_minVersion;
052    protected String m_maxVersion;
053    protected String m_adminBeanClass;
054    
055    /**
056     *  Create a new info container.
057     *  
058     *  @param name The name of the module.
059     */
060    public WikiModuleInfo( String name ) {
061        m_name = name;
062    }
063    
064    /**
065     *  The WikiModuleInfo is equal to another WikiModuleInfo, if the name is equal.  All
066     *  objects are unique across JSPWiki.
067     *  
068     *  @param obj {@inheritDoc}
069     *  @return {@inheritDoc}
070     */
071    @Override
072    public boolean equals(Object obj) {
073        if( obj instanceof WikiModuleInfo )
074        {
075            return ((WikiModuleInfo)obj).m_name.equals( m_name );
076        }
077        
078        return false;
079    }
080
081    /**
082     *  {@inheritDoc}
083     */
084    @Override
085    public int hashCode() {
086        return m_name.hashCode();
087    }
088
089    /**
090     *  Initializes the ModuleInfo from some standard XML elements
091     *  which are under the given element.
092     *  
093     *  @param el The element to parse.
094     */
095    protected void initializeFromXML( Element el ) {
096        m_description        = el.getChildText("description");
097        m_moduleUrl          = el.getChildText("url");
098        m_moduleVersion      = el.getChildText("version");
099        m_htmlTemplate       = el.getChildText("template");
100        m_scriptLocation     = el.getChildText("script");
101        m_stylesheetLocation = el.getChildText("stylesheet");
102        m_author             = el.getChildText("author");
103        m_authorUrl          = el.getChildText("authorUrl");
104        m_minVersion         = el.getChildText("minVersion");
105        m_maxVersion         = el.getChildText("maxVersion");
106        m_adminBeanClass     = el.getChildText("adminBean");
107    }
108
109    /**
110     *  Returns the AdminBean class which is supposed to manage this module.
111     *  
112     *  @return A class name.
113     */
114    public String getAdminBeanClass() {
115        return m_adminBeanClass;
116    }
117    
118    /**
119     *  Returns the common name for this particular module.  Note that
120     *  this is not the class name, nor is it an alias.  For different modules
121     *  the name may have different meanings.
122     *  <p>
123     *  Every module defines a name, so this method should never return null.
124     *  
125     *  @return A module name.
126     */
127    public String getName() {
128        return m_name;
129    }
130    
131    /**
132     *  The description of what this module does.
133     *  
134     *  @return A module description.
135     */
136    public String getDescription() {
137        return m_description;
138    }
139    
140    /**
141     *  The URL for this getting more information about this module.
142     *  
143     *  @return A module URL.
144     */
145    public String getModuleUrl() {
146        return m_moduleUrl;
147    }
148    
149    /**
150     *  The current version of the implemented module
151     *  
152     *  @return A module version.
153     */
154    public String getModuleVersion() {
155        return m_moduleVersion;
156    }
157    
158    /**
159     *  Return the location of the html template for this module.
160     *  
161     *  @return The path to the location.
162     */
163    public String getHtmlTemplate() {
164        return m_htmlTemplate;
165    }
166
167    /**
168     *  Returns the style sheet location for this module.
169     *  
170     *  @return The path to the location.
171     */
172    public String getStylesheetLocation() {
173        return m_stylesheetLocation;
174    }
175
176    /**
177     *  Return the location of the script for this module.
178     *  
179     *  @return The path to the location.
180     */
181    public String getScriptLocation() {
182        return m_scriptLocation;
183    }
184
185    /**
186     *  Returns the name of the author of this plugin (if defined).
187     * @return Author name, or null.
188     */
189    public String getAuthor() {
190        return m_author;
191    }
192
193    /**
194     *  Returns the url of the author of this plugin (if defined).
195     */
196    public String getAuthorUrl() {
197        return m_authorUrl;
198    }
199    
200    /**
201     *  Returns the minimum version of JSPWiki that this module supports.
202     *  
203     *  @return The minimum version.
204     */
205    public String getMinVersion() {
206        return m_minVersion;
207    }
208    
209    /**
210     *  Returns the maximum version of JSPWiki that this module supports.
211     *  
212     *  @return The maximum version.
213     */
214    public String getMaxVersion() {
215        return m_maxVersion;
216    }
217
218    /**
219     *  Attempts to locate a resource from a JAR file and returns it as a string.
220     *  
221     *  @param resourceLocation an URI of the resource
222     *  @return The content of the file
223     *  
224     *  @throws IOException if the JAR file or the resource cannot be read
225     */
226    protected String getTextResource(String resourceLocation) 
227        throws IOException
228    {
229        if(m_resource == null)
230        {
231            return "";
232        }
233    
234        // The text of this resource should be loaded from the same
235        //   jar-file as the jspwiki_modules.xml -file! This is because 2 plugins
236        //   could have the same name of the resourceLocation!
237        //   (2 plugins could have their stylesheet-files in 'ini/jspwiki.css')
238    
239        // So try to construct a resource that loads this resource from the
240        //   same jar-file.
241        String spec = m_resource.toString();
242    
243        // Replace the 'PLUGIN_RESOURCE_LOCATION' with the requested
244        //   resourceLocation.
245        int length = ModuleManager.PLUGIN_RESOURCE_LOCATION.length();
246        spec = spec.substring(0, spec.length() - length) + resourceLocation;
247    
248        URL url = new URL(spec);
249        BufferedInputStream   in  = new BufferedInputStream(url.openStream());
250        ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
251        
252        FileUtil.copyContents( in, out );
253    
254        in.close();
255        String text = out.toString();
256        out.close();
257        
258        return text;
259    }
260
261    /**
262     *  {@inheritDoc}
263     */
264    public int compareTo(WikiModuleInfo arg0)
265    {
266        return m_name.compareTo( arg0.getName() );
267    }
268
269}