You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/02/28 12:28:48 UTC

[isis] 02/03: ISIS-1841 make ProgrammingModel + SwaggerValueProperties plug-able

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 28dbe93816a513f667ab7967f61101b4cb6f3af9
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Feb 28 13:26:42 2018 +0100

    ISIS-1841 make ProgrammingModel + SwaggerValueProperties plug-able
---
 .../plugins/ProgrammingModelIsisTimePlugin.java    |  25 +++
 ...core.metamodel.progmodel.ProgrammingModelPlugin |   1 +
 ...l.services.swagger.internal.ValuePropertyPlugin |   1 +
 .../progmodel/ProgrammingModelPlugin.java          |  92 +++++++++++
 .../swagger/internal/ValuePropertyFactory.java     | 182 ++++++++-------------
 .../swagger/internal/ValuePropertyPlugin.java      |  45 +++++
 .../dflt/ProgrammingModelFacetsJava5.java          |  38 +++--
 7 files changed, 254 insertions(+), 130 deletions(-)

diff --git a/core/metamodel-legacy/src/main/java/org/apache/isis/progmodels/plugins/ProgrammingModelIsisTimePlugin.java b/core/metamodel-legacy/src/main/java/org/apache/isis/progmodels/plugins/ProgrammingModelIsisTimePlugin.java
new file mode 100644
index 0000000..e9588ff
--- /dev/null
+++ b/core/metamodel-legacy/src/main/java/org/apache/isis/progmodels/plugins/ProgrammingModelIsisTimePlugin.java
@@ -0,0 +1,25 @@
+package org.apache.isis.progmodels.plugins;
+
+import org.apache.isis.core.metamodel.facets.value.date.DateValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.datetime.DateTimeValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.time.TimeValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.timestamp.TimeStampValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.timestampsql.JavaSqlTimeStampValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModelPlugin;
+
+public class ProgrammingModelIsisTimePlugin implements ProgrammingModelPlugin {
+
+	@Override
+	public void plugin(FactoryCollector collector) {
+		
+		collector.addFactory(new DateValueFacetUsingSemanticsProviderFactory(), FacetFactoryCategory.VALUE);
+		collector.addFactory(new DateTimeValueFacetUsingSemanticsProviderFactory(), FacetFactoryCategory.VALUE);
+        
+		collector.addFactory(new TimeStampValueFacetUsingSemanticsProviderFactory(), FacetFactoryCategory.VALUE);
+		collector.addFactory(new TimeValueFacetUsingSemanticsProviderFactory(), FacetFactoryCategory.VALUE);
+		
+		collector.addFactory(new JavaSqlTimeStampValueFacetUsingSemanticsProviderFactory(), FacetFactoryCategory.VALUE);
+
+	}
+
+}
diff --git a/core/metamodel-legacy/src/main/resources/META-INF/services/org.apache.isis.core.metamodel.progmodel.ProgrammingModelPlugin b/core/metamodel-legacy/src/main/resources/META-INF/services/org.apache.isis.core.metamodel.progmodel.ProgrammingModelPlugin
new file mode 100644
index 0000000..4a74f84
--- /dev/null
+++ b/core/metamodel-legacy/src/main/resources/META-INF/services/org.apache.isis.core.metamodel.progmodel.ProgrammingModelPlugin
@@ -0,0 +1 @@
+org.apache.isis.progmodels.plugins.ProgrammingModelIsisTimePlugin
\ No newline at end of file
diff --git a/core/metamodel-legacy/src/main/resources/META-INF/services/org.apache.isis.core.metamodel.services.swagger.internal.ValuePropertyPlugin b/core/metamodel-legacy/src/main/resources/META-INF/services/org.apache.isis.core.metamodel.services.swagger.internal.ValuePropertyPlugin
new file mode 100644
index 0000000..9161c26
--- /dev/null
+++ b/core/metamodel-legacy/src/main/resources/META-INF/services/org.apache.isis.core.metamodel.services.swagger.internal.ValuePropertyPlugin
@@ -0,0 +1 @@
+org.apache.isis.core.metamodel.services.swagger.plugins.IsisTimeValuePropertyPlugin
\ No newline at end of file
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodel/ProgrammingModelPlugin.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodel/ProgrammingModelPlugin.java
new file mode 100644
index 0000000..2ea8a81
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodel/ProgrammingModelPlugin.java
@@ -0,0 +1,92 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.metamodel.progmodel;
+
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.isis.applib.internal.collections._Multimaps;
+import org.apache.isis.applib.internal.collections._Multimaps.SetMultimap;
+import org.apache.isis.core.metamodel.facets.FacetFactory;
+
+public interface ProgrammingModelPlugin {
+	
+	// -- CONTRACT
+	
+	/**
+	 * Guides the priority at which facet factories are registered.
+	 * There is no other use.
+	 */
+	public static enum FacetFactoryCategory {
+		// extend as needed ...
+		VALUE
+		;
+	}
+	
+	public static interface FactoryCollector {
+		
+		/**
+		 * 
+		 * @param factoryClass
+		 * @param category
+		 */
+	    public void addFactory(FacetFactory facetFactory, final FacetFactoryCategory category);
+	    
+	    /**
+	     * 
+	     * @param category
+	     * @return
+	     */
+	    public Set<FacetFactory> getFactories(FacetFactoryCategory category);
+	    
+	}
+	
+	public static FactoryCollector collector() {
+    	return new FactoryCollector() {
+			
+			final SetMultimap<FacetFactoryCategory, FacetFactory> factoriesByCategory =
+					_Multimaps.newSetMultimap();
+
+			@Override
+			public void addFactory(FacetFactory factory, FacetFactoryCategory category) {
+				Objects.requireNonNull(factory);
+				Objects.requireNonNull(category);
+				factoriesByCategory.putElement(category, factory);
+			}
+
+			@Override
+			public Set<FacetFactory> getFactories(final FacetFactoryCategory category) {
+				if(category==null) {
+					return Collections.emptySet();
+				}
+				return Collections.unmodifiableSet(
+						factoriesByCategory.getOrDefault(category, Collections.emptySet())	);
+						
+			}
+    	};
+    }
+	
+	// -- INTERFACE 
+	
+    public void plugin(FactoryCollector collector);
+    
+    // -- 
+	
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/ValuePropertyFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/ValuePropertyFactory.java
index 4d966bf..e76fd93 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/ValuePropertyFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/ValuePropertyFactory.java
@@ -23,19 +23,23 @@ import java.math.BigInteger;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.UUID;
+import java.util.function.Supplier;
 
 import javax.annotation.Nullable;
 
+import org.apache.isis.applib.internal.context._Plugin;
+import org.apache.isis.core.metamodel.services.swagger.internal.ValuePropertyPlugin.ValuePropertyCollector;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.joda.time.LocalDateTime;
+
 import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
-import org.joda.time.DateTime;
-import org.joda.time.LocalDate;
-import org.joda.time.LocalDateTime;
-
 import io.swagger.models.properties.BooleanProperty;
 import io.swagger.models.properties.ByteArrayProperty;
 import io.swagger.models.properties.DateProperty;
@@ -51,120 +55,55 @@ import io.swagger.models.properties.UUIDProperty;
 
 public class ValuePropertyFactory {
 
-    private final Map<Class, Factory> propertyFactoryByClass = Maps.newHashMap();
+    private final Map<Class<?>, Factory> propertyFactoryByClass = Maps.newHashMap();
 
-    static interface Factory {
-        Property newProperty();
-    }
+    public static interface Factory extends Supplier<Property> {};
+    
     public ValuePropertyFactory() {
 
-        final Factory booleanFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new BooleanProperty();
-            }
-        };
-        propertyFactoryByClass.put(boolean.class, booleanFactory);
-        propertyFactoryByClass.put(Boolean.class, booleanFactory);
-
-        final Factory integerFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new IntegerProperty();
-            }
-        };
-        propertyFactoryByClass.put(byte.class, integerFactory);
-        propertyFactoryByClass.put(Byte.class, integerFactory);
-        propertyFactoryByClass.put(short.class, integerFactory);
-        propertyFactoryByClass.put(Short.class, integerFactory);
-        propertyFactoryByClass.put(int.class, integerFactory);
-        propertyFactoryByClass.put(Integer.class, integerFactory);
-        propertyFactoryByClass.put(BigInteger.class, integerFactory);
-
-        final Factory longFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new LongProperty();
-            }
-        };
-        propertyFactoryByClass.put(long.class, longFactory);
-        propertyFactoryByClass.put(Long.class, longFactory);
-        propertyFactoryByClass.put(java.sql.Timestamp.class, longFactory);
-
-        final Factory decimalFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new DecimalProperty();
-            }
-        };
-        propertyFactoryByClass.put(BigDecimal.class, decimalFactory);
-
-        final Factory floatFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new FloatProperty();
-            }
-        };
-        propertyFactoryByClass.put(float.class, floatFactory);
-        propertyFactoryByClass.put(Float.class, floatFactory);
-
-        final Factory doubleFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new DoubleProperty();
-            }
-        };
-        propertyFactoryByClass.put(double.class, doubleFactory);
-        propertyFactoryByClass.put(Double.class, doubleFactory);
-
-        final Factory stringFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new StringProperty();
-            }
-        };
-        propertyFactoryByClass.put(char.class, stringFactory);
-        propertyFactoryByClass.put(Character.class, stringFactory);
-        propertyFactoryByClass.put(char[].class, stringFactory);
-        propertyFactoryByClass.put(String.class, stringFactory);
-
-        final Factory uuidFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new UUIDProperty();
-            }
-        };
-        propertyFactoryByClass.put(UUID.class, uuidFactory);
-
-        final Factory dateTimeFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new DateTimeProperty();
-            }
-        };
-        propertyFactoryByClass.put(java.util.Date.class, dateTimeFactory);
-        propertyFactoryByClass.put(DateTime.class, dateTimeFactory);
-        propertyFactoryByClass.put(LocalDateTime.class, dateTimeFactory);
-        propertyFactoryByClass.put(org.apache.isis.applib.value.DateTime.class, dateTimeFactory);
-
-        final Factory dateFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new DateProperty();
-            }
-        };
-        propertyFactoryByClass.put(java.sql.Date.class, dateFactory);
-        propertyFactoryByClass.put(LocalDate.class, dateFactory);
-        propertyFactoryByClass.put(org.apache.isis.applib.value.Date.class, dateFactory);
-
-        final Factory byteArrayFactory = new Factory() {
-            @Override
-            public Property newProperty() {
-                return new ByteArrayProperty();
-            }
-        };
-        propertyFactoryByClass.put(byte[].class, byteArrayFactory);
-        propertyFactoryByClass.put(org.apache.isis.applib.value.Blob.class, byteArrayFactory);
+        propertyFactoryByClass.put(boolean.class, BooleanProperty::new);
+        propertyFactoryByClass.put(Boolean.class, BooleanProperty::new);
+
+        propertyFactoryByClass.put(byte.class, IntegerProperty::new);
+        propertyFactoryByClass.put(Byte.class, IntegerProperty::new);
+        propertyFactoryByClass.put(short.class, IntegerProperty::new);
+        propertyFactoryByClass.put(Short.class, IntegerProperty::new);
+        propertyFactoryByClass.put(int.class, IntegerProperty::new);
+        propertyFactoryByClass.put(Integer.class, IntegerProperty::new);
+        propertyFactoryByClass.put(BigInteger.class, IntegerProperty::new);
+
+        propertyFactoryByClass.put(long.class, LongProperty::new);
+        propertyFactoryByClass.put(Long.class, LongProperty::new);
+        propertyFactoryByClass.put(java.sql.Timestamp.class, LongProperty::new);
+
+        propertyFactoryByClass.put(BigDecimal.class, DecimalProperty::new);
+
+        propertyFactoryByClass.put(float.class, FloatProperty::new);
+        propertyFactoryByClass.put(Float.class, FloatProperty::new);
+
+        propertyFactoryByClass.put(double.class, DoubleProperty::new);
+        propertyFactoryByClass.put(Double.class, DoubleProperty::new);
+
+        propertyFactoryByClass.put(char.class, StringProperty::new);
+        propertyFactoryByClass.put(Character.class, StringProperty::new);
+        propertyFactoryByClass.put(char[].class, StringProperty::new);
+        propertyFactoryByClass.put(String.class, StringProperty::new);
+
+        propertyFactoryByClass.put(UUID.class, UUIDProperty::new);
+
+        propertyFactoryByClass.put(java.util.Date.class, DateTimeProperty::new);
+        propertyFactoryByClass.put(DateTime.class, DateTimeProperty::new);
+        propertyFactoryByClass.put(LocalDateTime.class, DateTimeProperty::new);
+
+        propertyFactoryByClass.put(java.sql.Date.class, DateProperty::new);
+        propertyFactoryByClass.put(LocalDate.class, DateProperty::new);
+
+        propertyFactoryByClass.put(byte[].class, ByteArrayProperty::new);
+        propertyFactoryByClass.put(org.apache.isis.applib.value.Blob.class, ByteArrayProperty::new);
+        
+        // add propertyFactories from plugins
+        discoverValueProperties().visitEntries(propertyFactoryByClass::put);        
+        
     }
 
     public Property newProperty(Class<?> cls) {
@@ -174,7 +113,7 @@ public class ValuePropertyFactory {
 
         final Factory factory = propertyFactoryByClass.get(cls);
         if(factory != null) {
-            return factory.newProperty();
+            return factory.get();
         }
 
         // special case, want to treat as a value
@@ -194,5 +133,16 @@ public class ValuePropertyFactory {
 
         return null;
     }
+    
+    // -- HELPER
+    
+    private static ValuePropertyCollector discoverValueProperties() {
+	    final Set<ValuePropertyPlugin> plugins = _Plugin.load(ValuePropertyPlugin.class);
+	    final ValuePropertyCollector collector = ValuePropertyPlugin.collector();
+	    plugins.forEach(plugin->{
+	    	plugin.plugin(collector);
+	    });
+	    return collector;
+    }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/ValuePropertyPlugin.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/ValuePropertyPlugin.java
new file mode 100644
index 0000000..b55cb6b
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/swagger/internal/ValuePropertyPlugin.java
@@ -0,0 +1,45 @@
+package org.apache.isis.core.metamodel.services.swagger.internal;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+
+import org.apache.isis.applib.internal.collections._Maps;
+import org.apache.isis.core.metamodel.services.swagger.internal.ValuePropertyFactory.Factory;
+
+public interface ValuePropertyPlugin {
+
+	// -- CONTRACT
+	
+	public static interface ValuePropertyCollector {
+	    public void addValueProperty(final Class<?> cls, final ValuePropertyFactory.Factory factory);
+	    public void visitEntries(BiConsumer<Class<?>, ValuePropertyFactory.Factory> visitor);
+	}
+	
+	public static ValuePropertyCollector collector() {
+		
+		return new ValuePropertyCollector() {
+			
+			final Map<Class<?>, Factory> entries = _Maps.newHashMap();
+			
+			@Override
+			public void visitEntries(BiConsumer<Class<?>, Factory> visitor) {
+				Objects.requireNonNull(visitor);
+				entries.forEach(visitor);
+			}
+			
+			@Override
+			public void addValueProperty(Class<?> cls, Factory factory) {
+				Objects.requireNonNull(cls);
+				Objects.requireNonNull(factory);
+				entries.put(cls, factory);
+			}
+		};
+		
+	}
+	
+	// -- INTERFACE
+	
+	public void plugin(ValuePropertyCollector collector);
+	
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index 11ac0e1..57f3760 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -18,7 +18,9 @@
 package org.apache.isis.progmodels.dflt;
 
 import java.util.List;
+import java.util.Set;
 
+import org.apache.isis.applib.internal.context._Plugin;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.facets.actions.action.ActionAnnotationFacetFactory;
 import org.apache.isis.core.metamodel.facets.actions.action.ActionChoicesForCollectionParameterFacetFactory;
@@ -132,11 +134,9 @@ import org.apache.isis.core.metamodel.facets.value.chars.CharPrimitiveValueFacet
 import org.apache.isis.core.metamodel.facets.value.chars.CharWrapperValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.clobs.ClobValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.color.ColorValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.date.DateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datejdk8local.Jdk8LocalDateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datejodalocal.JodaLocalDateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datesql.JavaSqlDateValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.datetime.DateTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetimejdk8local.Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetimejdk8offset.Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetimejoda.JodaDateTimeValueFacetUsingSemanticsProviderFactory;
@@ -159,15 +159,15 @@ import org.apache.isis.core.metamodel.facets.value.percentage.PercentageValueFac
 import org.apache.isis.core.metamodel.facets.value.shortint.ShortPrimitiveValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.shortint.ShortWrapperValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.string.StringValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.time.TimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.timesql.JavaSqlTimeValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.timestamp.TimeStampValueFacetUsingSemanticsProviderFactory;
-import org.apache.isis.core.metamodel.facets.value.timestampsql.JavaSqlTimeStampValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.url.URLValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.uuid.UUIDValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.postprocessors.param.ActionCollectionParameterDefaultsAndChoicesPostProcessor;
 import org.apache.isis.core.metamodel.progmodel.ObjectSpecificationPostProcessor;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModelPlugin;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModelPlugin.FacetFactoryCategory;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModelPlugin.FactoryCollector;
 
 import com.google.common.collect.Lists;
 
@@ -179,7 +179,9 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
 
     public ProgrammingModelFacetsJava5(final DeprecatedPolicy deprecatedPolicy) {
         super(deprecatedPolicy);
-
+        
+        final FactoryCollector factoriesFromPlugins = discoverFactories();
+        
         // must be first, so any Facets created can be replaced by other
         // FacetFactorys later.
         addFactory(new FallbackFacetFactory());
@@ -348,8 +350,6 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         addFactory(new TypicalLengthFacetOnPropertyDerivedFromTypeFacetFactory());
         addFactory(new TypicalLengthFacetOnParameterDerivedFromTypeFacetFactory());
 
-        
-
 
         // built-in value types for Java language
         addFactory(new BooleanPrimitiveValueFacetUsingSemanticsProviderFactory());
@@ -373,7 +373,6 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         addFactory(new JavaSqlDateValueFacetUsingSemanticsProviderFactory());
         addFactory(new JavaSqlTimeValueFacetUsingSemanticsProviderFactory());
         addFactory(new JavaUtilDateValueFacetUsingSemanticsProviderFactory());
-        addFactory(new JavaSqlTimeStampValueFacetUsingSemanticsProviderFactory());
         addFactory(new StringValueFacetUsingSemanticsProviderFactory());
         addFactory(new URLValueFacetUsingSemanticsProviderFactory());
         addFactory(new LocalResourcePathValueFacetUsingSemanticsProviderFactory());
@@ -384,16 +383,12 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         // applib values
         addFactory(new BlobValueFacetUsingSemanticsProviderFactory());
         addFactory(new ClobValueFacetUsingSemanticsProviderFactory());
-        addFactory(new DateValueFacetUsingSemanticsProviderFactory());
-        addFactory(new DateTimeValueFacetUsingSemanticsProviderFactory());
         addFactory(new ColorValueFacetUsingSemanticsProviderFactory());
         addFactory(new MoneyValueFacetUsingSemanticsProviderFactory());
         addFactory(new PasswordValueFacetUsingSemanticsProviderFactory());
         addFactory(new PercentageValueFacetUsingSemanticsProviderFactory());
-        addFactory(new TimeStampValueFacetUsingSemanticsProviderFactory());
-        addFactory(new TimeValueFacetUsingSemanticsProviderFactory());
         addFactory(new ImageValueFacetUsingSemanticsProviderFactory());
-
+        
         // jodatime values
         addFactory(new JodaLocalDateValueFacetUsingSemanticsProviderFactory());
         addFactory(new JodaLocalDateTimeValueFacetUsingSemanticsProviderFactory());
@@ -404,6 +399,9 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         addFactory(new Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory());
         addFactory(new Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory());
         
+        // plugin value factories 
+        factoriesFromPlugins.getFactories(FacetFactoryCategory.VALUE).forEach(this::addFactory);
+        
         // written to not trample over TypeOf if already installed
         addFactory(new CollectionFacetFactory());
         // must come after CollectionFacetFactory
@@ -435,4 +433,16 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
             new ActionCollectionParameterDefaultsAndChoicesPostProcessor()
         );
     }
+    
+    // -- HELPER
+    
+    private static FactoryCollector discoverFactories() {
+	    final Set<ProgrammingModelPlugin> plugins = _Plugin.load(ProgrammingModelPlugin.class);
+	    final FactoryCollector collector = ProgrammingModelPlugin.collector();
+	    plugins.forEach(plugin->{
+	    	plugin.plugin(collector);
+	    });
+	    return collector;
+    }
+    
 }

-- 
To stop receiving notification emails like this one, please contact
ahuber@apache.org.