/*
* This file is part of muCommander, http://www.mucommander.com
* Copyright (C) 2002-2016 Maxence Bernard
*
* muCommander is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* muCommander is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.mucommander.extension;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import javax.swing.LookAndFeel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Class filter for look and feels.
* <p>
* This filter will only accept classes if:
* <ul>
* <li>They subclass <code>javax.swing.LookAndFeel</code>.</li>
* <li>They are public and not abstract.</li>
* <li>They have a public, no-arg constructor.</li>
* <li>Their <code>isSupportedLookAndFeel</code> method returns <code>true</code>.</li>
* <li>They are not an inner class.</li>
* </ul>
* </p>
* @author Nicolas Rinaudo
*/
public class LookAndFeelFilter implements ClassFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(LookAndFeelFilter.class);
/**
* Creates a new instance of <code>LookAndFeelFilter</code>.
*/
public LookAndFeelFilter() {}
/**
* Filters out everything but available look and feels.
* @param c class to check.
* @return <code>true</code> if c is an available look and feel, <code>false</code> otherwise.
*/
public boolean accept(Class<?> c) {
int modifiers; // Class' modifiers.
Constructor<?> constructor; // Public, no-arg constructor.
Class<?> buffer; // Used to explore c's ancestors.
// Ignores inner classes.
if(c.getDeclaringClass() != null)
return false;
// Makes sure the class is public and non abstract.
modifiers = c.getModifiers();
if(!Modifier.isPublic(modifiers) || Modifier.isAbstract(modifiers))
return false;
// Makes sure the class has a public, no-arg constructor.
try {constructor = c.getDeclaredConstructor(new Class[0]);}
catch(Exception e) {return false;}
if(!Modifier.isPublic(constructor.getModifiers()))
return false;
// Makes sure the class extends javax.swing.LookAndFeel and that if it does,
// it's supported by the system.
buffer = c;
while(buffer != null) {
// c is a LookAndFeel, makes sure it's supported.
if(buffer.equals(LookAndFeel.class)) {
try {return ((LookAndFeel)c.newInstance()).isSupportedLookAndFeel();}
catch(Throwable e) {
LOGGER.debug("Caught exception", e);
return false;
}
}
buffer = buffer.getSuperclass();
}
return false;
}
}