I have class Foo, which derived from interface IFoo and IEnumerable
public class Foo:IFoo,IEnumerable
{
public decimal Count {...}
///etc...
}
How to call GetProperties(), that it's return only public properties of IEnumerable (not IFoo or this class)?
To get the properties of IEnumerable, you don't even need to reference Foo:
typeof(IEnumerable).GetProperties();
Once you have the properties and you're ready to get values using the PropertyInfo object, then you can pass it an instance of the Foo class to get the values from.
Related
I already know how to add annotation based validation on specific attributes in Entity class like :-
public class Person {
#NotNull
private String firstName;
private String lastName;
//...
}
But is it possible to add annotation on class Person, in order to validate all the attributes inside this class, by creating a Customised Validation Class and handling validation there somewhere like :-
#Retention(value = RetentionPolicy.RUNTIME)
#Target(value = ElementType.METHOD)
public #interface PersonneName {
public String firstName();
}
I am working on a project to get Constraints from Database and creating Customised Validation Class and applying on the Entity class attributes according to the constaints got from DB.
Please suggest.
Yes, of course, it's possible. First, create the definition of your annotation. Pretty much like you did in your example, however, with a different #Target type
#Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Constraint(validatedBy = PersonValidator.class)
public #interface ValidPerson {
String message () default "Your custom message";
Class<?>[] groups () default {};
Class<? extends Payload>[] payload () default {};
}
Then implement the validator whose isValid method takes the instance of your Person class:
public class PersonValidator implements ConstraintValidator<ValidPerson, Person> {
#Override
public boolean isValid (Person person, ConstraintValidatorContext context) {
// your validation logic
}
}
Sure it is possible, just check the documentation regarding how to write custom class level constraints - http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-class-level-constraints
The important thing of course is that you make sure that one can actually place the constraint annotation on the type level. For that you need to add ElementType.TYPE to the #Target annotation.
I have a class that I loaded using Objectify v5, how do I get the associated Key<T> from Objectify?
#Entity
#Cache
public abstract class BaseEntity<T,P>
{
#Parent
private Key<P> parent;
#Id
private String uuid;
}
I know that ofy().save() returns the Key<T> but I want to get the Key<T> from an Entity that was loaded by a filter or id.
I have searched all over the Objectify v5 documentation and can't find methods that take an Entity and return a Key<T> of that Entity.
Solution
Key.create(T pojo);
But in the case above it doesn't work from inside my BaseEntity<T,P> class.
#Nonnull
public Key<T> getKey() { return Key.create(this); }
Complains that it wants to cast the result to Key<T>.
After some experimenting I just added a method to my BaseEntity
#Nonnull
public Key<T> getKey()
{
return Key.create(this.parent, this.entityType, this.uuid.toString());
}
This returns the same Key<T> that is auto-generated.
Java's typing system is not sophisticated enough to express "i want this to be whatever type 'this' happens to be at the leaf level" (since you are in an abstract class). Scala could do this, but not Java. At least not to my knowledge.
Unless I'm misunderstanding what you are trying to do...?
Assuming I have an Interface IReportBuilderService and concrete class ReportBuilderService
e.g. public class ReportBuilderService : IReportBuilderService { }
I can start to mock this service with Moq as such
Mock<IReportBuilderService> _reportBuilderServiceMock = new Mock<IReportBuilderService>();
And mock expectations etc on the mock class, ok no problems.
Question: How do I mock the following method signature?
public abstract class ReportBuilder<TReport> where TReport : Report, new()
where a TReport is defined as
public class SomeReport : ReportBuilder<Report>, IMapper{}
And Report class is simply
public class Report { }
In the abstract class ReportBuilder there are a series of Property Get/ Sets, it is the value of these that I’m trying to fake/mock.
But I can’t begin to get the correct mock on this abstract class to start with
Hope this makes sense
Given that your abstract class looks like this:
public abstract class ReportBuilder<TReport> where TReport : Report, new()
{
public abstract Int32 SomeThing { get; set; }
}
there's no problem in mocking it at all:
var m = new Mock<ReportBuilder<Report>>();
m.SetupProperty(r => r.SomeThing, 19);
but note that all your properties have to be virtual or abstract.
So if this is not the case (and you can't or don't want to change this), you could either extract an interface from your base class and use this (if you're willing to change your code accordingly), or simply create a stub/mock by subclassing:
public class StubReportBuilder : ReportBuilder<Report>
{
public override Int32 SomeThing { get { return 42; } set { } }
}
I have 3 simple classes:
public abstract class Container implements WritableComparable<Container> {} //empty
public class WeightedEdge extends Container { ... }
public class NodeWeightContainer extends Container { ... }
The Map phase was configured as such
JobConf createGraphPConf = new JobConf(new Configuration());
Job job = new Job(createGraphPConf);
...
createGraphPConf.setMapOutputValueClass(Container.class);
However I am receiving this error:
java.io.IOException: Type mismatch in value from map: expected org.hadoop.test.data.util.Container, recieved org.hadoop.test.data.WeightedEdge
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1018)
at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:591)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:33)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:19)
at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:435)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:371)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:210)
Why I can't return a subclass of a class that was defined in the configuration? Is there a way around it? The problem is that my Map phase has to emit two distinct object types.
You can not return a subclass of a class that was defined in the configuration because Hadoop explicitly checks class type specified in setMapOutputValueClass and the type it receives from Mappers.
It does so because it needs to serialize/deserialize objects you emit from mappers. When it performs deserialization it creates new object of type that is specified in setMapOutputValueClass call and then uses methods of WriteableComparable interface to fill newly created object with data.
To be able to emit different object types you may define container non-abstract class and place actual object and its type identifier inside
public enum ELEM_TYPE { WE, WECONTAINER }
public class Container implements WritableComparable<Container>
{
ELEM_TYPE type; //actual element type -
// WeightedEdge or NodeWeightContainer
object value;
//WritableComparable implementation
// that casts value to the appropriate type
}
public class WeightedEdge { ... }
public class NodeWeightContainer { ... }
I faced the same problem today. There is a Writable class org.apache.hadoop.io.GenericWritable which can be used to address this problem. You need to extend the class and implement an abstract method:
public class Container extends GenericWritable {
private static Class[] CLASSES = {
WeightedEdge.class,
NodeWeightContainer.class,
};
protected Class[] getTypes() {
return CLASSES;
}
}
public class WeightedEdge implemets Writable {...}
public class NodeWeightContainer implements Writable {...}
Now you can use the class Container as the output value type of your mapper.
Important: Your actual map output classes (WeightedEdge and NodeWeightContainer) must implement the Writable interface.
Is there a way to override an abstract class's method signature which uses <T> with a ClassName so I can pass an object by reference without recasting it?
For example, I have a bunch of Object Managers. I want them all to contain a .Save(Object) method which will perform the appropriate save action based on the object state (Insert, Update, Delete, etc).
I was trying to create a base class which contains these methods:
protected virtual bool Update<T>(ref T _object) where T : ObjectBase
{
throw new NotImplementedException();
}
public virtual bool Save<T>(ref T _object) where T : ObjectBase
{
// Figure out which action to take based on _object's state and execute it
}
And I wanted my inherited classes to define the methods using something like this:
public override bool Update<Consumer>(ref Consumer _object)
{
return _service.UpdateConsumer(ref _object);
}
My problem is that I can't specify that <T> will now be <Consumer>, and by keeping it at <T> I can't pass it by ref
Instead of making the methods themselves generic, you should make the entire base class generic.
For example:
public abstract class ObjectManager<T> where T : ObjectBase {
protected abstract bool Update(T obj);
}
Each concrete ObjectManager should inherit ObjectManager of the type that it manages, like this:
public class ConsumerManager : ObjectManager<Consumer> {
protected override bool Update(Consumer obj) {
...
}
}
Note, by the way, that your parameters should almost definitely not be passed ref.
You only need to ref keyword if you want to change the caller's variable to refer to a different instance.
For more information, see here.