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