View Javadoc

1   package de.campussource.cse.cdmm.domain;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import javax.persistence.CascadeType;
7   import javax.persistence.Entity;
8   import javax.persistence.Inheritance;
9   import javax.persistence.InheritanceType;
10  import javax.persistence.JoinTable;
11  import javax.persistence.ManyToMany;
12  import javax.persistence.ManyToOne;
13  import javax.persistence.OneToMany;
14  import javax.persistence.Table;
15  import javax.xml.bind.annotation.XmlElement;
16  import javax.xml.bind.annotation.XmlElementWrapper;
17  import javax.xml.bind.annotation.XmlIDREF;
18  import javax.xml.bind.annotation.XmlRootElement;
19  import javax.xml.bind.annotation.XmlTransient;
20  import javax.xml.bind.annotation.XmlType;
21  
22  import de.campussource.cse.cdmm.Constants;
23  
24  /**
25   * Category entity object
26   * 
27   * @author Sebastian Roekens
28   * 
29   */
30  @Entity(name = Constants.CATEGORY)
31  @Inheritance(strategy = InheritanceType.JOINED)
32  @Table(name = Constants.TABLENAME_CATEGORY)
33  @XmlRootElement(namespace = Constants.NAMESPACE_DATATYPES)
34  @XmlType(name = Constants.CATEGORY_TYPE, propOrder = { Constants.PROPERTY_PARENT, Constants.PROPERTY_CHILDREN,
35  		Constants.PROPERTY_COURSES }, namespace = Constants.NAMESPACE_DATATYPES)
36  public class Category extends de.campussource.cse.cdmm.domain.Entity {
37  
38  	@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
39  	@JoinTable(name = Constants.COLUMNNAME_CATEGORY2CATEGORY)
40  	private Category parent;
41  
42  	@OneToMany(mappedBy = Constants.PARENT, cascade = { CascadeType.REMOVE })
43  	private List<Category> children;
44  
45  	@ManyToMany(mappedBy = Constants.CATEGORIES)
46  	private List<Course> courses;
47  
48  	public Category() {
49  	}
50  
51  	public Category(Long id) {
52  		setId(id);
53  	}
54  
55  	/**
56  	 * Convenience method for dependency check to prevent circular dependencies.
57  	 * True if circular dependency would be created.
58  	 * 
59  	 * @param newChildCategory
60  	 *            new child category to be added to this
61  	 * @return true, if newChildCategory is present in hierarchy above this,
62  	 *         else false
63  	 */
64  	private boolean checkForCircularDependencies(Category newChildCategory) {
65  		if (this.getId() != null && this.equals(newChildCategory)) {
66  			return true;
67  		}
68  		if (this.getId() == null && this != newChildCategory) {
69  			return false;
70  		}
71  		if (this.isRoot()) {
72  			return false;
73  		}
74  		return this.parent.checkForCircularDependencies(newChildCategory);
75  	}
76  
77  	/**
78  	 * Private method for adding category to list of children. If list of
79  	 * children does not exist, it is created.
80  	 * 
81  	 * @param category
82  	 *            child category
83  	 * @return success of operation
84  	 */
85  	private boolean addChild(Category category) {
86  		if (this.children == null) {
87  			this.children = new ArrayList<Category>();
88  		}
89  		if (checkForCircularDependencies(category)) {
90  			return false;
91  		}
92  		return this.children.add(category);
93  	}
94  
95  	/**
96  	 * Convenience method for parent <-> children connection of categories.
97  	 * Parent of this is set to parent category and list of children of parent
98  	 * category is updated with this.
99  	 * 
100 	 * @param parent
101 	 *            parent category
102 	 * @return Success of operation
103 	 */
104 	public boolean addToParentCategory(Category parent) {
105 		this.parent = parent;
106 		return parent.addChild(this);
107 	}
108 
109 	@XmlElementWrapper(name = Constants.CATEGORIES)
110 	@XmlElement(name = Constants.CATEGORY)
111 	public List<Category> getChildren() {
112 		return children;
113 	}
114 
115 	public void setChildren(List<Category> children) {
116 		this.children = children;
117 	}
118 
119 	@XmlElementWrapper(name = Constants.COURSES)
120 	@XmlElement(name = Constants.COURSE)
121 	@XmlIDREF
122 	public List<Course> getCourses() {
123 		return courses;
124 	}
125 
126 	public void setCourses(List<Course> courses) {
127 		this.courses = courses;
128 	}
129 
130 	@XmlElement(name = Constants.PARENT)
131 	@XmlIDREF
132 	public Category getParent() {
133 		return parent;
134 	}
135 
136 	public void setParent(Category parent) {
137 		this.parent = parent;
138 	}
139 
140 	/**
141 	 * Convenience method for checking if category is root category.
142 	 * 
143 	 * @return true if category is root category, else returning false
144 	 */
145 	@XmlTransient
146 	public boolean isRoot() {
147 		return (parent == null);
148 	}
149 
150 }