/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package foam.core;

import java.util.Collections;
import java.util.Map;

public class SimpleFacetManager
  implements FacetManager
{

  public Object getInstanceOf(Object value, Class type, X x) {
    return create(type, x);
  }

  public <T> T create(Class<T> type, X x) {
    return create(type, Collections.<String, Object>emptyMap(), x);
  }

  public <T> T create(Class<T> type, Map<String, Object> args, X x) {
    try {
      // Automatically load FooImpl if Foo is abstract.
      // KGR: Why/where do we do this?
      // KGR: I Think this is wrong. If Foo is Abstract it should be called AbstractFoos
      if ( java.lang.reflect.Modifier.isAbstract(type.getModifiers()) ) {
        type = (Class<T>) Class.forName(type.getName() + "Impl");
      }

      try {
        java.lang.reflect.Method method = type.getMethod("getOwnClassInfo");
        ClassInfo classInfo = (ClassInfo) method.invoke(null);

        // First check the context for a custom factory for this type of object.
        // If there's nothing in the context, check the ClassInfo for an axiom
        // that creates instances of this type of object. Singletons and
        // multitons are common examples of this type of axiom.
        Object f = null;
        if ( x.get(classInfo.getId() + "_Factory") != null ) {
          f = x.get(classInfo.getId() + "_Factory");
        } else if ( classInfo.getAxiomsByClass(XArgsFactory.class).size() == 1 ) {
          f = classInfo.getAxiomsByClass(XArgsFactory.class).get(0);
        }

        if ( f != null ) {
          return ((XArgsFactory<T>) f).getInstance(args, x);
        }

      } catch (NoSuchMethodException e) {
      }

      T obj = type.newInstance();

      if ( obj instanceof ContextAware ) ((ContextAware) obj).setX(x);

      if ( obj instanceof FObject ) {
        for ( Map.Entry<String, Object> entry : args.entrySet() )
          ((FObject) obj).setProperty(entry.getKey(), entry.getValue());
      }

      return obj;
    } catch (java.lang.Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }
}

@@ -530,24 +530,175 @@
 rgs, X x) %7B%0A
+    if ( type == foam.core.FObject.class ) %7B%0A      Thread.dumpStack();%0A      System.err.println(%22Unable to create FObject.%22);%0A      return null;%0A    %7D%0A
     try %7B%0A  
@@ -691,24 +691,24 @@
 %7D%0A    try %7B%0A
-
       // Aut
@@ -949,24 +949,40 @@
 iers()) ) %7B%0A
+        try %7B%0A  
         type
@@ -1031,24 +1031,96 @@
  + %22Impl%22);%0A
+        %7D catch (ClassNotFoundException e) %7B%0A          // NOP%0A        %7D%0A
       %7D%0A%0A   
@@ -2348,27 +2348,17 @@
 ch (
-java.lang.Exception
+Throwable
  e) 

Remove errors when attempting to create Impl classes from abstract classes.