View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.util.annotation;
35  
36  import fr.paris.lutece.portal.service.util.AppLogService;
37  import fr.paris.lutece.portal.service.util.AppPathService;
38  
39  import org.scannotation.AnnotationDB;
40  
41  import java.io.File;
42  import java.io.FilenameFilter;
43  import java.io.IOException;
44  
45  import java.lang.annotation.Annotation;
46  
47  import java.net.MalformedURLException;
48  import java.net.URL;
49  
50  import java.util.Date;
51  import java.util.HashSet;
52  import java.util.Map;
53  import java.util.Set;
54  
55  
56  /**
57   * Uses {@link AnnotationDB} from scannotation.
58   * @see #init()
59   */
60  public class ScannotationDB implements IAnnotationDB
61  {
62      private static final String CONSTANT_WEB_INF_LIB = "/WEB-INF/lib/";
63      private static final String CONSTANT_WEB_INF_CLASS = "/WEB-INF/classes/";
64  
65      /**
66       * Default filename filter matches <strong>ONLY</strong> lutece jars.
67       */
68      private static final String CONSTANT_DEFAULT_FILENAME_FILTER = "(plugin-.*\\.jar)|(module-.*\\.jar)|(lutece-core-.*\\.jar)|(library-.*\\.jar)";
69      private final AnnotationDB _db;
70      private String _strFileFilter;
71  
72      /**
73       * Constructor.
74       */
75      public ScannotationDB(  )
76      {
77          _db = new AnnotationDB(  );
78      }
79  
80      /**
81       * Gets the filename filter
82       * @return the filename filter
83       */
84      public String getFileFilter(  )
85      {
86          return _strFileFilter;
87      }
88  
89      /**
90       * Sets the filename filter
91       * @param strFileFilter the filename filter
92       */
93      public void setFileFilter( String strFileFilter )
94      {
95          _strFileFilter = strFileFilter;
96      }
97  
98      /**
99       * Scans the WEB-INF/classes and WEB-INF/lib using {@link #getFileFilter()}
100      * to filter jars.
101      */
102     @Override
103     public void init(  )
104     {
105         AppLogService.info( "ScannotationDB Scanning classpath..." );
106 
107         if ( getFileFilter(  ) == null )
108         {
109             setFileFilter( CONSTANT_DEFAULT_FILENAME_FILTER );
110             AppLogService.info( "Using default filename filter" );
111         }
112         else
113         {
114             AppLogService.info( "Using " + getFileFilter(  ) + " as filename filter" );
115         }
116 
117         Date start = new Date(  );
118         File libDirectory = new File( AppPathService.getWebAppPath(  ) + CONSTANT_WEB_INF_LIB );
119 
120         String[] allJars = libDirectory.list( new FilenameFilter(  )
121                 {
122                     /**
123                      * {@inheritDoc}
124                      */
125                     @Override
126                     public boolean accept( File dir, String name )
127                     {
128                         return name.matches( _strFileFilter );
129                     }
130                 } );
131 
132         for ( String strJar : allJars )
133         {
134             try
135             {
136                 if ( AppLogService.isDebugEnabled(  ) )
137                 {
138                     AppLogService.debug( "Scanning " + strJar );
139                 }
140 
141                 _db.scanArchives( new URL( "file:///" + AppPathService.getWebAppPath(  ) + CONSTANT_WEB_INF_LIB +
142                         strJar ) );
143             }
144             catch ( MalformedURLException e )
145             {
146                 AppLogService.error( e.getMessage(  ), e );
147             }
148             catch ( IOException e )
149             {
150                 AppLogService.error( e.getMessage(  ), e );
151             }
152         }
153 
154         AppLogService.info( "ScannotationDB WEB-INF/lib scanned" );
155 
156         try
157         {
158             _db.scanArchives( new URL( "file:///" + AppPathService.getWebAppPath(  ) + CONSTANT_WEB_INF_CLASS ) );
159         }
160         catch ( MalformedURLException e )
161         {
162             AppLogService.error( e.getMessage(  ), e );
163         }
164         catch ( IOException e )
165         {
166             AppLogService.error( e.getMessage(  ), e );
167         }
168 
169         AppLogService.info( "ScannotationDB Classpath scanned in " + ( new Date(  ).getTime(  ) - start.getTime(  ) ) +
170             "ms" );
171     }
172 
173     /**
174      * {@inheritDoc}
175      */
176     @Override
177     public Set<String> getClassesName( Class<?extends Annotation> annotationType )
178     {
179         return getClassesName( annotationType.getName(  ) );
180     }
181 
182     /**
183      * {@inheritDoc}
184      */
185     @Override
186     public Set<String> getClassesName( String strAnnotationType )
187     {
188         Map<String, Set<String>> index = _db.getAnnotationIndex(  );
189 
190         Set<String> setClasses = index.get( strAnnotationType );
191 
192         if ( setClasses == null )
193         {
194             setClasses = new HashSet<String>(  );
195         }
196 
197         return setClasses;
198     }
199 }