Suggestions how to break up projects with #XmlSeeAlso limiting me - jaxb

I'd like to start breaking apart a large domain project into various smaller sub projects. The issue is that I have an external project that has some code that needs to unmarshal some xml into a top level base class that all the subprojects can share as a common base. This would be fine, except that I will need an #XmlSeeAlso on the base class that would include every possible subclass (so it seems.) This seems to make it impossible for me to break up the projects in the way I planned.
For example, using animals just for illustration.
Without the XmlSeeAlso on Animal defining the subclasses, I'm pretty much stuck.
//Core project jar
public abstract class Animal {
}
//Mammals jar
#XmlSeeAlso({ Dog.class, Cat.class})
public abstract class Mammal extends Animal {
}
//Birds jar
#XmlSeeAlso({ Sparrow.class, Hawk.class})
public abstract class Bird extends Animal {
}
//Third party jar
//use Bird or Mammal xml
input = new ByteArrayInputStream(birdXml.getBytes());
JAXBContext jc = JAXBContext.newInstance(Animal.class);
u = jc.createUnmarshaller();
//return Animal - FAILS since Animal would need the XmlSeeAlso of subclasses
Animal animal = (Animal)u.unmarshal(input);

I didn't realize that JAXBContext.newInstance can take an array of classes. So in my third party jar I just need to load them all into some common Array and pass them in there to the newInstance method ... JAXBContext.newInstance(myClassesArray);

Related

Initializing objects using a super class instead of the subclass

I recently saw this example code and I didn't know how I'd be able to easily find the answer to this question I had. In the code the Dog object, Cow object and Snake object are all declared as Animal objects. So is it valid to declare an object using a more generic class? For instance, could I declare any object as an Object (since all classes are subclasses of the object class)? What are the advantages/disadvantages of declaring specific or more general? Is it all for ease of readability?
class Animal {
void whoAmI() {
System.out.println("I am a generic Animal.");
}
}
class Dog extends Animal {
void whoAmI() {
System.out.println("I am a Dog.");
}
}
class Cow extends Animal {
void whoAmI() {
System.out.println("I am a Cow.");
}
}
class Snake extends Animal {
void whoAmI() {
System.out.println("I am a Snake.");
}
}
class RuntimePolymorphismDemo {
public static void main(String[] args) {
Animal ref1 = new Animal();
Animal ref2 = new Dog();
Animal ref3 = new Cow();
Animal ref4 = new Snake();
ref1.whoAmI();
ref2.whoAmI();
ref3.whoAmI();
ref4.whoAmI();
}
}
The output is
I am a generic Animal.
I am a Dog.
I am a Cow.
I am a Snake.
You could instantiate every other class with object, but not primitives, though even they have wrappers that make them classes.
It's just not good object oriented practice because you want the program to be as fail safe as possible.
Put more varied methods into those classes and that's when you start to see the problems.
lets say Dog also has the method chewButt().
Animal dog = new Dog();
dog.chewButt();
No problem there. But that's not all you're allowed to do.
Animal dog = new Cow();
that compiles...
dog.chewButt();
now we have a problem. Cow can't reach its butt.
You want to be as stringent as possible when declaring the superclass but loose enough to get your job done fast. A reason you may want to be looser is something like this.
dogs and snakes are a little too different. I'mma create a new subclass Mammal that extends from Animal. I put dog and cow and whatever else in it.
now I can be assured I can do:
Mammal mouse = new Mouse();
mouse.suckleYoung();
cat.suckleYoung();
whale.suckleYoung();
but if I accidentally try:
Mammal snake = new Snake();
I want the compiler to complain now before I dig myself into a coding hole.
I hope that helps. Experience will definitely burn the points into your brain soon enough.
Edit: referencing comment: I still don't get what reasons there would be that I wouldn't always just declare my dog object like "Dog dog = new Dog();" vs. how it is in the example code "Animal dog = new Dog();
It's because your function working on dog is also assured to work with all Animals (dogs, cats, lizards). If you went with the other route you would have to go through the trouble of writing a separate function for each class of animal. What's worse is that every function you made would have the same code. Instead write the methods once in Animal and every extended class has that set of methods. Imagine having realized that the method you wrote was slightly wrong, you had to change one line but you had to do it in every animal's module because you didn't take the time to create an Animal superclass.

Groovy AST - Adding annotations at compilation

I'm trying to dynamicly crate an annotation that will dynamicaly add an #XmlElement annotation to every field in a class using metaprogramming and AST. I'm having problems creating the annotations and applying them to the fields properly.
The code i have is formatted here: http://pastebin.com/60DTX5Ya
import javax.xml.bind.annotation.XmlElement
#GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
class WebserviceAnnotationModifier implements ASTTransformation {
#Override
void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {
if (!astNodes) return
if (!astNodes[0] || !astNodes[1]) return
if (!(astNodes[0] instanceof AnnotationNode)) return
if (!(astNodes[1] instanceof ClassNode)) return
ClassNode node = (ClassNode)astNodes[1]
List fields = node.getFields()
fields.each {FieldNode field ->
field.addAnnotation(ClassHelper.make(new XmlElement.DEFAULT()));
}
}
}
#Retention(RetentionPolicy.SOURCE)
#Target([ElementType.TYPE])
#GroovyASTTransformationClass(classes =[WebserviceAnnotationModifier])
public #interface WebresourceAnnotation{}
#WebresourceAnnotation
class TestPerson{
String name;
String lastName;
int Age
}
Am i approaching this all wrong? The reason i do this is i have a domain that is still in the making and i'd like to just go in and apply the annotation to all fields. Couldn't find any examples of annotations added during compilation. Is this not possible?
Writing codes using Groovy AST Transformation alone does not work with the Grails reloading mechanism. Here's a proper way to implement AST transformation for a Grails app.
Your transformer class must extends AbstractGrailsArtefactTransformer.
Your transformer class must be annotated by #AstTransformer.
You class must be put under org.codehaus.groovy.grails.compiler or its sub-package. In my case I use org.codehaus.groovy.grails.compiler.zk and it's working fine.
Implement shouldInject() to match only classes you want, in this case domain classes.
Override performInjection() and write your codes there.
Pack your transformer and releated classes into a .jar file, or Grails compiler does not load it.

Adding to a dictionary c#

I have a dictionary that contains classes. However, I have a lot of classes to add to the dictionary and I would like to eliminate the long list of adds, because it's starting to look messy. I was thinking of having all the data in a file and loading it to add to the dictionary, but then I realized that every time I wanted to create and add a new class, I would have to modify the file. I would prefer to have to include something in my newly created class that would automatically add it to the dictionary. I'm not even sure this is possible, so I would appreciate any help.
Try to use reflection to dynamically locate all the required classes. Create an instance of Assembly where your classes are defined and try to filter them out. An example below shows how to locate all the classes whose name ends with Task.
var assembly = Assembly.GetExecutingAssembly();
var taskTypes = assembly.GetTypes()
.Where(t => t.Name.EndsWith("Task") && t.IsClass);
Dictionary<string, object> instances =
new Dictionary<string, object>(taskTypes.Count());
foreach (Type classType in taskTypes)
{
object instance = Activator.CreateInstance(classType);
instances.Add(classType.Name, instance);
Console.WriteLine("Registered key {0} with object of type {1})",
classType.Name,
instance);
}
I've used Activator.CreateInstance method to create instances of your classes, but this might not be possible in your case depending on whether they have parameterless contructors etc.
Another option might be to use one of the available IoC containers like autofac but I need more details on your problem before I can give a proper advice on this.
Make the dictionary a static field of some class, or make the "add class to dictionary" a static method.
Then, you can use a static constructor to add each class to the dictionary:
class ClassDict {
...
public static void AddClass(Type t) {
...
}
}
class Foo {
static Foo() {
ClassDict.AddClass(typeof(Foo));
}
}

UML relationship of a static call from another class

I am creating a class diagram but I was wondering if there would be any association between the 2 classes shown below - as far as I understand it, for association, ClassA must have an instance of ClassB which in this case there is not, however, it does need to know about a variable of ClassB, so is there an association between these 2 classes?
public class ClassA()
{
int val = ClassB.x
}
public class ClassB()
{
public static int x = 5;
}
Sure there is association. You can't use ClassA without existing of ClassB.
Yes there is an association between these two classes. The association is neither an aggregation nor a composition, it is a "uses/usage" dependency.
ClassA ------Uses-----> ClassB
Take a look at this link to know more about different types of dependencies

How to dynamically create collections of derived objects?

This question may appear to have been answered before but I have been unable to find exactly what I need. Here is my situation:
// Base class
interface IAnimal {};
public abstract class Animal : IAnimal{}
// Derived classes
interface IDog {}
public class Dog : Animal, IDog { }
interface ICat { }
public class Cat : Animal, ICat { }
interface ITiger { }
public class Tiger : Animal, ITiger { }
interface ILion { }
public class Lion : Animal, ILion { }
// Collection Classes
interface IPets { }
public class Pets
{
IDog dog = new Dog();
ICat cat = new Cat();
}
interface ICircus { }
public class Circus
{
ITiger tiger = new Tiger();
ILion lion = new Lion();
}
I would like to create the collections at run time in an generic Event class by reading in a list animals from xml that would make up the collection. What would be the correct way to accomplish this?
Thanks in advance.
This is kind of an answer to my own question. Maybe this will help others.
I chose a very generic example to illustrate my situation because I have uses for this in many places in Windows Forms, XNA and Silverlight that are all very different.
When I used the Activator, I found out that it assumes the executing assembly. My method is in a library so I had to load a different assembly. Next I had to make sure that I had the right namespace. My base class is in a library and the derived classes are in another namespace so this will require refactoring to properly create the list.
Another problem I found was that the Activator assumes a constructor with no parameters. In my test case all my derived classes are XNA game components with a parameter of type Game.
Have to do some refactoring to test out the interfaces and how the game objects are to interact.
Will be back to this list when I have something further.
Does this sort of example help? (It's from some of my code I happened to have handy.) The key point here is the use of reflection in Activator.CreateInstance(...).
public static List<dynamic> LoadChildEntities(XElement entityElt)
{
var children = new List<dynamic>();
foreach(XElement childElt in entityElt.Elements("entity"))
{
// Look up the C# type of the child entity.
string childTypename = "MyNamespace." + Convert.ToString(childElt.Attribute("type").Value);
Type childType = Type.GetType(childTypename);
if(childType != null)
{
// Construct the child entity and add it to the list.
children.Add(Activator.CreateInstance(childType, childElt));
}
else
{
throw new InvalidOperationException("No such class: " + childTypename);
}
}
return children;
}
If you want a list of IAnimal instead, it wouldn't be too tricky to change.

Resources