Skip to content

Commit

Permalink
Cache ElementImpl constructor and silence warning
Browse files Browse the repository at this point in the history
  • Loading branch information
matthiasblaesing committed Feb 4, 2023
1 parent 4c39ae9 commit b1486d3
Showing 1 changed file with 19 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
*/
package org.netbeans.modules.css.model.impl;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.modules.css.lib.api.Node;
Expand Down Expand Up @@ -184,20 +188,32 @@ public Element createElement(Model model, Node node) { //NOI18N for whole method
return new PlainElementI(model, node);
default:
//fallback for unknown types
Logger.getLogger(ElementFactoryImpl.class.getName()).log( Level.WARNING, "created element by reflection for {0}, update the ElementFactoryImpl.createElement() methods ugly switch!", className);
return createElementByReflection(model, node);
return createElementByReflection(model, node, className);
}
}

private Element createElementByReflection(Model model, Node node) {
private static final Map<NodeType, Reference<Constructor<?>>> reflectiveImplementations = new ConcurrentHashMap<>();
private Element createElementByReflection(Model model, Node node, String interfaceName) {
Parameters.notNull("model", model);
Parameters.notNull("node", node);
try {
Reference<Constructor<?>> implConstructorRef = reflectiveImplementations.get(node.type());
Constructor<?> implConstructor = implConstructorRef == null ? null : implConstructorRef.get();
if(implConstructor != null) {
return (Element) implConstructor.newInstance(model, node);
}
Logger.getLogger(ElementFactoryImpl.class.getName()).log( Level.FINE, "created element by reflection for {0}, update the ElementFactoryImpl.createElement() methods ugly switch!", interfaceName);
Class<?> clazz = Class.forName(Utils.getImplementingClassNameForNodeType(node.type()));
Constructor<?> constructor = clazz.getConstructor(Model.class, Node.class);
reflectiveImplementations.put(node.type(), new WeakReference<>(constructor));
return (Element) constructor.newInstance(model, node);
} catch (ClassNotFoundException cnfe ) {
//no implementation found - use default
try {
reflectiveImplementations.put(node.type(), new WeakReference<>(PlainElementI.class.getConstructor(Model.class, Node.class)));
} catch (NoSuchMethodException ex) {
throw new RuntimeException(cnfe);
}
return new PlainElementI(model, node);
} catch (IllegalAccessException | IllegalArgumentException | InstantiationException
| NoSuchMethodException | SecurityException | InvocationTargetException ex) {
Expand Down

0 comments on commit b1486d3

Please sign in to comment.