Skip to content

Commit

Permalink
Broken generics in Facet API
Browse files Browse the repository at this point in the history
  • Loading branch information
lincolnthree committed Jun 13, 2013
1 parent e6d84c4 commit 87dcacd
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>, <a
* href="http://community.jboss.org/people/kenfinni">Ken Finnigan</a>
*/
public abstract class AbstractFacet<FACETED extends Faceted<?>> implements Facet<FACETED>, MutableOrigin<FACETED>
public abstract class AbstractFacet<FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>>
implements Facet<FACETEDTYPE, FACETTYPE>, MutableOrigin<FACETEDTYPE, FACETTYPE>
{
protected FACETED origin;
protected FACETEDTYPE origin;

@Override
public FACETED getOrigin()
public FACETEDTYPE getOrigin()
{
return this.origin;
}

/**
* Set the <FACETED> origin on which this {@link Facet} will operate.
* Set the <FACETEDTYPE> origin on which this {@link Facet} will operate.
*/
@Override
public void setOrigin(FACETED origin)
public void setOrigin(FACETEDTYPE origin)
{
this.origin = origin;
}
Expand Down Expand Up @@ -58,7 +59,7 @@ public boolean equals(final Object obj)
return false;
if (getClass() != obj.getClass())
return false;
AbstractFacet<?> other = (AbstractFacet<?>) obj;
AbstractFacet<?, ?> other = (AbstractFacet<?, ?>) obj;
if (origin == null)
{
if (other.origin != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
*
* @param <FACETTYPE> the base {@link Facet} type supported by this {@link Faceted} type.
*/
public abstract class AbstractFaceted<FACETTYPE extends Facet<?>> implements MutableFaceted<FACETTYPE>
public abstract class AbstractFaceted<FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>>
implements MutableFaceted<FACETEDTYPE, FACETTYPE>
{
private Set<FACETTYPE> facets = Collections.newSetFromMap(new ConcurrentHashMap<FACETTYPE, Boolean>());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@
* A {@link Facet} is an access point to common functionality, file manipulations, descriptors that extend a
* {@link Faceted} instance. When implementing this interface, consider extending {@link AbstractFacet} for convenience.
*
* @param <FACETED> The {@link Faceted} type to which this {@link Facet} may attach.
* @param <FACETEDTYPE> The {@link Faceted} type to which this {@link Facet} may attach.
*
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
* @author <a href="http://community.jboss.org/people/kenfinni">Ken Finnigan</a>
*
* @see {@link AbstractFacet}
*/
@Exported
public interface Facet<FACETED extends Faceted<?>>
public interface Facet<FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>>
{
/**
* Return the {@link Faceted} instance on which this {@link Facet} operates.
*/
FACETED getOrigin();
FACETEDTYPE getOrigin();

/**
* Perform necessary setup for this {@link Facet} to be considered installed in the given {@link Faceted} instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,32 @@ public interface FacetFactory
*
* @throws FacetNotFoundException if no implementation can be found.
*/
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> FACET create(Class<FACET> type)
throws FacetNotFoundException;
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> FACETTYPE create(
Class<FACETTYPE> type) throws FacetNotFoundException;

/**
* Create a new instance of the given {@link Facet} type. If it is also an instance of {@link MutableOrigin}, then
* use the given origin instance as the {@link Facet#getOrigin()}.
*
* @throws FacetNotFoundException if no implementation can be found.
*/
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> FACET create(Class<FACET> type, E origin)
throws FacetNotFoundException;
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> FACETTYPE create(
Class<FACETTYPE> type, FACETEDTYPE origin) throws FacetNotFoundException;

/**
* Get all instantiable {@link Facet} instances implementing the given {@link Facet} type. Returns an empty
* {@link Iterable} if no matching implementations can be found.
*/
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> Iterable<FACET> createFacets(Class<FACET> type);
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> Iterable<FACETTYPE> createFacets(
Class<FACETTYPE> type);

/**
* Get all instantiable {@link Facet} instances implementing the given {@link Facet} type. If it is also an instance
* of {@link MutableOrigin}, then use the given origin instance as the {@link Facet#getOrigin()}. Returns an empty
* {@link Iterable} if no matching implementations can be found.
*/
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> Iterable<FACET> createFacets(
Class<FACET> type, E origin);
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> Iterable<FACETTYPE> createFacets(
Class<FACETTYPE> type, FACETEDTYPE origin);

/**
* Create and installs a new instance of the given {@link Facet} type.
Expand All @@ -55,8 +56,8 @@ public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> Iterable<
* @throws FacetNotFoundException if no implementation can be found.
* @throws IllegalStateException if installation failed
*/
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> FACET install(Class<FACET> type, E origin)
throws FacetNotFoundException;
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> FACETTYPE install(
Class<FACETTYPE> type, FACETEDTYPE origin) throws FacetNotFoundException;

/**
* Install a {@link Facet} instance into the given origin.
Expand All @@ -67,6 +68,6 @@ public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> FACET ins
*
* @return <code>true</code> if installation was successful; <code>false</code> if installation failed.
*/
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> boolean install(FACET facet, E origin)
throws IllegalArgumentException;
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> boolean install(
FACETTYPE facet, FACETEDTYPE origin) throws IllegalArgumentException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*
* @param <FACETTYPE> the base {@link Facet} type supported by this {@link Faceted} type.
*/
public interface Faceted<FACETTYPE extends Facet<?>>
public interface Faceted<FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>, FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>>
{
/**
* Return true if a facet of the given type is present; return false otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
*
* @param <FACETTYPE> the base {@link Facet} type supported by this {@link MutableFaceted} type.
*/
public interface MutableFaceted<FACETTYPE extends Facet<?>> extends Faceted<FACETTYPE>
public interface MutableFaceted<FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>>
extends Faceted<FACETTYPE, FACETEDTYPE>
{
/**
* Install and register the given {@link Facet}. If the facet is already installed, return true.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
*
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
public interface MutableOrigin<FACETED extends Faceted<?>> extends Facet<FACETED>
public interface MutableOrigin<FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>>
extends Facet<FACETEDTYPE, FACETTYPE>
{
/**
* Set the {@link Faceted} origin to which this {@link Facet} belongs. Should only be set once, since each
* {@link Faceted} instance receives its own unique instance of all compatible {@link Facet} types. This method must
* be called before invoking any operations on {@code this} instance.
*/
void setOrigin(FACETED origin);
void setOrigin(FACETEDTYPE origin);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.jboss.forge.addon.facets.constraints;

import java.util.ArrayList;
import java.util.List;

import org.jboss.forge.addon.facets.Facet;
import org.jboss.forge.addon.facets.Faceted;
import org.jboss.forge.furnace.util.Annotations;

/**
* Used to inspect types that may or may not depend on {@link Facet}s or packaging types.
*
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
public abstract class FacetInspector
{
/**
* Inspect the given {@link Class} for any dependencies to {@link Facet} types.
*/
@SuppressWarnings("unchecked")
public static <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> List<Class<FACETTYPE>> getRequiredFacets(
final Class<FACETTYPE> type)
{
List<Class<FACETTYPE>> result = new ArrayList<Class<FACETTYPE>>();

if (Annotations.isAnnotationPresent(type, RequiresFacet.class))
{
RequiresFacet requires = Annotations.getAnnotation(type, RequiresFacet.class);
if (requires.value() != null)
{
for (Class<? extends Facet<?, ?>> facetType : requires.value())
{
if (Facet.class.isAssignableFrom(facetType))
result.add((Class<FACETTYPE>) facetType);
}
}
}

return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.jboss.forge.addon.projects.facets;
package org.jboss.forge.addon.facets.constraints;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.jboss.forge.addon.projects.ProjectFacet;
import org.jboss.forge.addon.facets.Facet;
import org.jboss.forge.addon.facets.Faceted;

/**
* The annotated element requires the given {@link ProjectFacet}
* The annotated element requires the given {@link Facet} types.
*
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
Expand All @@ -26,7 +27,7 @@
public @interface RequiresFacet
{
/**
* The facets required by the annotated {@link ProjectFacet}
* The facets required by the annotated {@link Faceted}
*/
Class<? extends ProjectFacet>[] value();
Class<? extends Facet<?, ?>>[] value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
*/
package org.jboss.forge.addon.facets;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;

import org.jboss.forge.addon.facets.constraints.FacetInspector;
import org.jboss.forge.furnace.addons.AddonRegistry;
import org.jboss.forge.furnace.services.ExportedInstance;
import org.jboss.forge.furnace.util.Assert;
Expand All @@ -24,48 +27,51 @@ public class FacetFactoryImpl implements FacetFactory
private AddonRegistry registry;

@Override
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> FACET create(Class<FACET> type)
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> FACETTYPE create(
Class<FACETTYPE> type)
{
Assert.notNull(type, "Facet type must not be null.");
ExportedInstance<FACET> instance = registry.getExportedInstance(type);
ExportedInstance<FACETTYPE> instance = registry.getExportedInstance(type);
if (instance == null)
throw new FacetNotFoundException("Could not find Facet of type [" + type.getName() + "]");
return instance.get();
}

@Override
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> FACET create(Class<FACET> type, E origin)
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> FACETTYPE create(
Class<FACETTYPE> type, FACETEDTYPE origin)
{
FACET instance = create(type);
FACETTYPE instance = create(type);
if (instance instanceof MutableOrigin)
((MutableOrigin<E>) instance).setOrigin(origin);
((MutableOrigin<FACETEDTYPE, FACETTYPE>) instance).setOrigin(origin);
else
throw new IllegalArgumentException("Facet type [" + type.getName() + "] does not support setting an origin.");
return instance;
}

@Override
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> Iterable<FACET> createFacets(Class<FACET> type)
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> Iterable<FACETTYPE> createFacets(
Class<FACETTYPE> type)
{
Assert.notNull(type, "Facet type must not be null.");
Set<ExportedInstance<FACET>> instances = registry.getExportedInstances(type);
Set<FACET> facets = new HashSet<FACET>(instances.size());
for (ExportedInstance<FACET> instance : instances)
Set<ExportedInstance<FACETTYPE>> instances = registry.getExportedInstances(type);
Set<FACETTYPE> facets = new HashSet<FACETTYPE>(instances.size());
for (ExportedInstance<FACETTYPE> instance : instances)
{
facets.add(instance.get());
}
return facets;
}

@Override
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> Iterable<FACET> createFacets(
Class<FACET> type, E origin)
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> Iterable<FACETTYPE> createFacets(
Class<FACETTYPE> type, FACETEDTYPE origin)
{
Iterable<FACET> facets = createFacets(type);
for (FACET facet : facets)
Iterable<FACETTYPE> facets = createFacets(type);
for (FACETTYPE facet : facets)
{
if (facet instanceof MutableOrigin)
((MutableOrigin<E>) facet).setOrigin(origin);
((MutableOrigin<FACETEDTYPE, FACETTYPE>) facet).setOrigin(origin);
else
throw new IllegalArgumentException("Facet type [" + type.getName()
+ "] does not support setting an origin.");
Expand All @@ -74,10 +80,11 @@ public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> Iterable<
}

@Override
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> FACET install(Class<FACET> type, E origin)
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> FACETTYPE install(
Class<FACETTYPE> type, FACETEDTYPE origin)
throws FacetNotFoundException
{
FACET facet = create(type, origin);
FACETTYPE facet = create(type, origin);
if (!install(facet, origin))
{
throw new IllegalStateException("Facet type [" + type.getName()
Expand All @@ -90,30 +97,46 @@ public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> FACET ins

@Override
@SuppressWarnings("unchecked")
public <FACET extends Facet<E>, E extends Faceted<? extends Facet<?>>> boolean install(FACET facet, E origin)
public <FACETEDTYPE extends Faceted<FACETTYPE, FACETEDTYPE>, FACETTYPE extends Facet<FACETEDTYPE, FACETTYPE>> boolean install(
FACETTYPE facet, FACETEDTYPE origin)
{
Assert.notNull(origin, "Facet instance must not be null.");
Assert.notNull(origin, "Origin instance must not be null.");

Faceted<FACET> faceted = (Faceted<FACET>) origin;
Faceted<FACETTYPE, FACETEDTYPE> faceted = (Faceted<FACETTYPE, FACETEDTYPE>) origin;
Assert.isTrue(faceted instanceof MutableFaceted, "The given origin [" + origin + "] is not an instance of ["
+ MutableFaceted.class.getName() + "], and does not support " + Facet.class.getSimpleName()
+ " installation.");

if (facet.getOrigin() == null && facet instanceof MutableOrigin)
{
((MutableOrigin<E>) facet).setOrigin(origin);
((MutableOrigin<FACETEDTYPE, FACETTYPE>) facet).setOrigin(origin);
}

Assert.isTrue(origin.equals(facet.getOrigin()), "The given origin [" + origin + "] is not an instance of ["
+ MutableFaceted.class.getName() + "], and does not support " + Facet.class.getSimpleName()
+ " installation.");

List<Class<FACETTYPE>> requiredFacets = FacetInspector.getRequiredFacets(facet.getClass());
List<Class<FACETTYPE>> facetsToInstall = new ArrayList<Class<FACETTYPE>>();
for (Class<FACETTYPE> requirement : requiredFacets)
{
if (!origin.hasFacet(requirement))
{
facetsToInstall.add(requirement);
}
}

for (Class<FACETTYPE> requirement : facetsToInstall)
{
install(requirement, origin);
}

boolean result = false;
if (faceted.hasFacet((Class<? extends FACET>) facet.getClass()))
if (faceted.hasFacet((Class<? extends FACETTYPE>) facet.getClass()))
result = true;
else
result = ((MutableFaceted<FACET>) faceted).install(facet);
result = ((MutableFaceted<FACETEDTYPE, FACETTYPE>) faceted).install(facet);
return result;
}
}

0 comments on commit 87dcacd

Please sign in to comment.