<%@ jet package="org.eclipse.jpt.jpa.ui.internal.wizards.entity" 
	imports="org.eclipse.jpt.jpa.ui.internal.wizards.entity.data.model.* java.util.* " 
	class="AnnotatedEntityTemplate" 
%>
<% CreateEntityTemplateModel model = (CreateEntityTemplateModel) argument; 
if (model.getJavaPackageName()!=null && model.getJavaPackageName()!="") { %>package <%=model.getJavaPackageName()%>;<%}%>

<% Collection<String> imports = model.getImports(false);
for (String anImport : imports) { %>
import <%=anImport%>;
<% } %>

/**
 * Entity implementation class for Entity: <%=model.getEntityName()%>
 *
 */
<%=model.getArtifactType()%><%String ENTITY_NAME = model.getEntityName();
if (model.isEntityNameSet()) {%>(name="<%=ENTITY_NAME%>")<%}%>
<%if (model.isTableNameSet()) {%>
@Table(name="<%=model.getTableName()%>")<%}%>
<%=model.getInheritanceStrategy()%>
<%if (model.isCompositePK()) {%>
@IdClass(<%=model.getIdClassName()%>.class)<%}%>
public class <%=model.getClassName()%><%String superClass = model.getSuperclassName();
	if (! "".equals(superClass)) {%> extends <%=superClass%><%}%><%
	List<String> interfaces = model.getInterfaces(); 
	if (interfaces.size()>0) {%> implements <% }
	for (int i=0; i<interfaces.size(); i++) {
 		String INTERFACE = (String) interfaces.get(i);
		if (i>0) { %>, <%}%><%=INTERFACE%><%}%> {

	<% List<EntityRow> fields = model.getEntityFields();
	List<String> pkFields = model.getPKFields(); 
 	for (EntityRow entity : fields) {
		String NAME = entity.getName();
		if (pkFields.contains(NAME) && model.isFieldAccess()) {
    %>   
	@Id<%}%>
	private <%=entity.getType()%> <%=entity.getName()%>;<%}%>
	private static final long serialVersionUID = 1L;

	public <%=model.getClassName()%>() {
		super();
	}
   <%
	fields = model.getEntityFields();
	if (fields != null) for (int i=0; i<fields.size(); i++) {
		EntityRow field = (EntityRow) fields.get(i);
		String TYPE = field.getType();
		String NAME = field.getName();
		String METHOD = NAME.substring(0,1).toUpperCase() + NAME.substring(1);
	if (pkFields.contains(NAME) && !model.isFieldAccess()) {
    %>   
	@Id <%}%>   
	public <%=TYPE%> get<%=METHOD%>() {
		return this.<%=NAME%>;
	}

	public void set<%=METHOD%>(<%=TYPE%> <%=NAME%>) {
		this.<%=NAME%> = <%=NAME%>;
	}
   <%}%>
   
}
