2121import org .dom4j .Document ;
2222import org .dom4j .Element ;
2323import org .dom4j .Node ;
24+ import org .slf4j .LoggerFactory ;
2425import org .pentaho .platform .api .engine .IContentGeneratorInfo ;
2526import org .pentaho .platform .api .engine .IPentahoSession ;
2627import org .pentaho .platform .api .engine .IPlatformPlugin ;
4849import java .io .File ;
4950import java .io .FilenameFilter ;
5051import java .util .ArrayList ;
52+ import java .util .Arrays ;
5153import java .util .Collection ;
5254import java .util .Collections ;
5355import java .util .List ;
@@ -64,6 +66,7 @@ public class SystemPathXmlPluginProvider implements IPluginProvider {
6466
6567 public static final String CLASS_PROPERRTY = "class" ;
6668 private static final Pattern PLUGIN_DATE_STAMP_REGEX = Pattern .compile ( "([\\ w\\ -]+)-2\\ d{3}-[\\ d\\ -]+" );
69+ private static final org .slf4j .Logger log = LoggerFactory .getLogger ( SystemPathXmlPluginProvider .class );
6770
6871 /**
6972 * Gets the list of plugins that this provider class has discovered.
@@ -83,6 +86,7 @@ public List<IPlatformPlugin> getPlugins( IPentahoSession session ) throws Platfo
8386 "PluginManager.ERROR_0004_CANNOT_FIND_SYSTEM_FOLDER" ) ); //$NON-NLS-1$
8487 }
8588 File [] kids = systemDir .listFiles ();
89+ Arrays .sort ( kids ); // default sort is by name, which is what we want
8690 // look at each child to see if it is a folder
8791 for ( File kid : kids ) {
8892 if ( kid .isDirectory () ) {
@@ -102,8 +106,11 @@ public List<IPlatformPlugin> getPlugins( IPentahoSession session ) throws Platfo
102106 return Collections .unmodifiableList ( plugins );
103107 }
104108
109+ @ SuppressWarnings ( "squid:S3776" ) // cannot break down into smaller methods without reducing readability
105110 protected void processDirectory ( List <IPlatformPlugin > plugins , File folder , IPentahoSession session )
106111 throws PlatformPluginRegistrationException {
112+
113+ log .debug ( "Processing plugin directory: {}" , folder .getAbsolutePath () );
107114 // see if there is a plugin.xml file
108115 FilenameFilter filter = new NameFileFilter ( "plugin.xml" , IOCase .SENSITIVE ); //$NON-NLS-1$
109116 File [] kids = folder .listFiles ( filter );
@@ -114,13 +121,15 @@ protected void processDirectory( List<IPlatformPlugin> plugins, File folder, IPe
114121 FilenameFilter deleteFilter = new NameFileFilter ( ".plugin-manager-delete" , IOCase .SENSITIVE ); //$NON-NLS-1$
115122 kids = folder .listFiles ( deleteFilter );
116123 if ( kids != null && kids .length > 0 ) {
124+ log .debug ( "Deleting plugin directory marked for deletion: {}" , folder .getAbsolutePath () );
117125 deleteFolder ( folder );
118126 return ;
119127 }
120128 // see if we should ignore this plugin because it is marked to be ignored
121129 FilenameFilter ignoreFilter = new NameFileFilter ( ".kettle-ignore" , IOCase .SENSITIVE ); //$NON-NLS-1$
122130 kids = folder .listFiles ( ignoreFilter );
123131 if ( kids != null && kids .length > 0 ) {
132+ log .debug ( "Ignoring plugin directory marked to be ignored: {}" , folder .getAbsolutePath () );
124133 return ;
125134 }
126135
@@ -144,7 +153,19 @@ protected void processDirectory( List<IPlatformPlugin> plugins, File folder, IPe
144153 // XML document can't be read. We'll just return a null document.
145154 }
146155 if ( doc != null ) {
147- plugins .add ( createPlugin ( doc , session , folder .getName (), hasLib ) );
156+ PlatformPlugin newPlugin = createPlugin ( doc , session , folder .getName (), hasLib );
157+ // make sure we don't already have a plugin with this id
158+ if ( plugins .stream ().anyMatch ( p -> p .getId ().equals ( newPlugin .getId () ) ) ) {
159+ String msg =
160+ Messages .getInstance ().getErrorString (
161+ "PluginManager.ERROR_0024_PLUGIN_ALREADY_LOADED_BY_SAME_NAME" , newPlugin .getId (), folder //$NON-NLS-1$
162+ .getAbsolutePath () );
163+ Logger .error ( getClass ().toString (), msg );
164+ PluginMessageLogger .add ( msg );
165+ log .warn ( "Plugin with id {} already loaded, skipping plugin in folder {}" , newPlugin .getId (), path );
166+ } else {
167+ plugins .add ( newPlugin );
168+ }
148169 }
149170 } catch ( Exception e ) {
150171 throw new PlatformPluginRegistrationException ( Messages .getInstance ().getErrorString (
@@ -163,6 +184,7 @@ protected void processDirectory( List<IPlatformPlugin> plugins, File folder, IPe
163184 */
164185 private File cleanUpUninstalledPlugins ( File folder , FilenameFilter deleteFilter , FilenameFilter ignoreFilter ) {
165186 // strip off any datestamp left from the plugin manager to leave only the base folder name
187+ log .debug ( "Checking for datestamp on plugin folder: {}" , folder .getAbsolutePath () );
166188 String newFolderName = stripDateStampFromFolderName ( folder .getName () );
167189 if ( !folder .getName ().equals ( newFolderName ) ) {
168190 // The plugin folder had a date stamp on the end of the name which was removed.
@@ -178,6 +200,7 @@ private File cleanUpUninstalledPlugins( File folder, FilenameFilter deleteFilter
178200 File [] deleteFiles = oldPluginFolder .listFiles ( deleteFilter );
179201 if ( null != ignoreFiles && ignoreFiles .length == 1 && null != deleteFiles && deleteFiles .length == 1 ) {
180202 // we can and should delete this folder before we rename the other one
203+ log .debug ( "Deleting old plugin folder marked for deletion: {}" , oldPluginFolder .getAbsolutePath () );
181204 deleteFolder ( oldPluginFolder );
182205 canRenameFolder = true ;
183206 } else {
@@ -208,6 +231,7 @@ private void deleteFolder( File folder ) {
208231 // delete the folder and its contents
209232 try {
210233 FileUtils .deleteDirectory ( folder );
234+ log .debug ( "Deleted plugin directory: {}" , folder .getAbsolutePath () );
211235 String msg = Messages .getInstance ().getString (
212236 "PluginManager.PLUGIN_FOLDER_DELETED" , folder .getAbsolutePath () );
213237 Logger .info ( getClass ().toString (), msg );
0 commit comments