gt: 			Date now = new Date();
context: package gr.ntua.ivml.mint.actions;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.util.ArrayList;
  import java.util.Date;
  import java.util.Iterator;
  import java.util.List;
  
  import gr.ntua.ivml.mint.db.DB;
  import gr.ntua.ivml.mint.persistent.BlobWrap;
  import gr.ntua.ivml.mint.persistent.DataUpload;
  import gr.ntua.ivml.mint.persistent.Mapping;
  import gr.ntua.ivml.mint.persistent.Organization;
  import gr.ntua.ivml.mint.persistent.Thesaurus;
  import gr.ntua.ivml.mint.persistent.ThesaurusAssignment;
  import gr.ntua.ivml.mint.persistent.User;
  import gr.ntua.ivml.mint.persistent.XpathHolder;
  
  import net.sf.json.JSONObject;
  
  import org.apache.log4j.Logger;
  import org.apache.struts2.convention.annotation.Action;
  import org.apache.struts2.convention.annotation.Result;
  import org.apache.struts2.convention.annotation.Results;
  import org.hibernate.Hibernate;
  
  import com.opensymphony.xwork2.ActionContext;
  
  @Results( {
  		@Result(name = "input", location = "editor.jsp"),
  		@Result(name = "error", location = "error.jsp", type = "redirectAction"),
  		@Result(name = "success", location = "ajaxthesaurus.jsp") })
  public class ThesaurusAction extends GeneralAction {
  	private static final int MAX_LABEL_LENGTH = 20;
  	protected final Logger log = Logger.getLogger(getClass());
  	private String result;
  	private String uploadId;
  	private String thesaurusId;
  	private String action;
  	private String xpath;
  	private String mappingId;
  	private String filename;
  	private String contentType;
  	
  	//Used for storing/retrieving thesaurus
  	private String description;
  	private String title;
  	private String url;
  	private String contact;
  	private File uploadFile;
  	
  	public String getUploadId() {
  		return uploadId;
  	}
  
  	public void setUploadId(String uploadId) {
  		this.uploadId = uploadId;
  	}
  
  	public String getAction() {
  		return action;
  	}
  
  	public void setAction(String action) {
  		this.action = action;
  	}
  
  	public String getResult() {
  		return result;
  	}
  
  	public void setResult(String result) {
  		this.result = result;
  	}
  
  	public String getXpath() {
  		return xpath;
  	}
  
  	public void setXpath(String xpath) {
  		log.info("*** Xpath from request set to : " + xpath); 
  		this.xpath = xpath;
  	}
  		
  
  	public String getThesaurusId() {
  		return thesaurusId;
  	}
  
  	public void setThesaurusId(String thesaurusId) {
  		this.thesaurusId = thesaurusId;
  	}
  
  	public String getMappingId() {
  		return mappingId;
  	}
  
  	public void setMappingId(String mappingId) {
  		this.mappingId = mappingId;
  	}	
  	
  	
  	///////////////////////////////////////////////
  	public void setUploadFileContentType(String contentType) {
  		this.contentType = contentType;
  	}
  
  	public void setUploadFileFileName(String filename) {
  		this.filename = filename;
  	}
  
  	public String getDescription() {
  		return description;
  	}
  
  	public void setDescription(String description) {
  		this.description = description;
  	}
  
  	public String getTitle() {
  		return title;
  	}
  
  	public void setTitle(String title) {
  		this.title = title;
  	}
  
  	public String getUrl() {
  		return url;
  	}
  
  	public void setUrl(String url) {
  		this.url = url;
  	}
  
  	public String getContact() {
  		return contact;
  	}
  
  	public void setContact(String contact) {
  		this.contact = contact;
  	}	
  
  	public File getUploadFile() {
  		return uploadFile;
  	}
  
  	public void setUploadFile(File uploadFile) {
  		this.uploadFile = uploadFile;
  	}
  
  	
  	///////////////////////////////////////////////
  	
  	
  	@Action(value = "ThesaurusAjax")
  	public String execute() throws Exception {
  		log.info("********************");
  		log.info("Thesaurus action - " + action);
  		log.info("upload id: " + uploadId);
  		log.info("Xpath: " + xpath);
  		if (action.equalsIgnoreCase("STATS")) {
  			//Return statistics
  			handleStatsRequest();
  		} else if(action.equalsIgnoreCase("LIST")) {
  			//Return list of thesauri for specified tree
  			handleThesaurusList();
  		} else if(action.equalsIgnoreCase("LABELS")) {
  			//Return list of labels for specific tree and thesauri
  			handleLabelList();
  		} else if(action.equalsIgnoreCase("SAVE")) {
  			//Save thesaurus
  			saveThesaurus();
  		} else if(action.equalsIgnoreCase("EDIT")) {
  			//Edit thesaurus
  			editThesaurus();
  		} else if(action.equalsIgnoreCase("EDIT_FORM")) {
  			//Create edit form for thesaurus
  			thesaurusEditForm();
  		} else if(action.equalsIgnoreCase("ASSIGN")) {
  			//Assign thesaurus to node
  			createThesaurusAssignment();
  		} else if(action.equalsIgnoreCase("UNASSIGN")) {
  			//Delete assignment of thesaurus to node
  			deleteThesaurusAssignment();
  		} else if(action.equalsIgnoreCase("DELETE")) {
  			//Delete thesaurus
  			deleteThesaurus();
  		} else if(action.equalsIgnoreCase("APPLY_THESAURUS")) {
  			//Apply current thesaurus assignments to current mapping
  			applyThesaurusToMapping();
  		}
  		log.info("********************");
  
  		return "success";
  	}
  	
  	private void deleteThesaurus() {
  		try {
  			result = "ERROR";
  			Thesaurus t = DB.getThesaurusDAO().findById(Long.valueOf(thesaurusId), false);
  			if((t != null) && (hasAccess(t.getOrganization()))) {
  				boolean r = DB.getThesaurusDAO().delete(Long.valueOf(thesaurusId));
  				if(r)
  					result = "OK";
  			}
  		} catch(Exception e) {
  			log.info("Error deleting thesaurus: " + e.getMessage());
  			result = "Error deleting thesaurus... <!--" + e.getMessage() + " -->";
  		}
  	}
  
  	private void deleteThesaurusAssignment() {
  		try {
  			result = "ERROR";
  			log.info("deleteThesaurusAssignment -> Mapping id: " + mappingId);
  			ThesaurusAssignment ta = DB.getThesaurusAssignmentDAO().findById(Long.valueOf(mappingId), false);
  			if((ta != null) && (hasAccess(ta.getUser().getOrganization()))) {
  				boolean r = DB.getThesaurusAssignmentDAO().delete(Long.valueOf(mappingId));
  				if(r)
  					result = "OK";
  			}
  		} catch(Exception e) {
  			log.info("Error deleting thesaurus assignment: " + e.getMessage());
  			result = "Error deleting thesaurus assignment... <!--" + e.getMessage() + " -->";
  		}
  	}
  	
  	private void createThesaurusAssignment() {
  		try {
  			log.info("Creating new thesaurus assignment...");
  			log.info("\tThesaurus ID: " + thesaurusId);
  			log.info("\tData Upload ID: " + uploadId);
  			Thesaurus t = DB.getThesaurusDAO().findById(Long.valueOf(thesaurusId), false);
  			DataUpload d = DB.getDataUploadDAO().findById(Long.valueOf(uploadId), false);
  			persistThesaurusAssignment(t, d, findXpathHolder());
  			result = "Succesfully added!";
  		} catch(Exception e) {
  			log.info("Error assigning thesaurus: " + e.getMessage());
  			result = "Error assigning thesaurus... <!--" + e.getMessage() + " -->";
  		}
  	}
  	
  	private void applyThesaurusToMapping() {
  		try {
  			int count = 0;
  			log.info("Applying mappings of thesarus with id " + thesaurusId + " to current mapping (" + uploadId + ")...");
  			Thesaurus t = DB.getThesaurusDAO().findById(Long.valueOf(thesaurusId), false);
  			DataUpload du = DB.getDataUploadDAO().findById(Long.valueOf(uploadId), false);
  			List l = DB.getThesaurusDAO().findDistinctXpathsByThesaurusId(t);
  			log.info("Detected total of " + l.size() + " already existing mappings");
  			if(l == null) {
  				log.info("Empty list of assignments - cannot apply...");
  			} else {
  				Iterator iter = l.iterator();
  				while(iter.hasNext()) {
  					//Attempt to find xpath
  					String xpath = (String) iter.next();
  					XpathHolder xpathHolder = findXpathHolder(xpath);
  					if((xpathHolder != null) && (!DB.getThesaurusAssignmentDAO().existsAssignment(xpathHolder, t, du))) {
  						//Xpath exists also in this tree, apply thesaurus
  						persistThesaurusAssignment(t, du, xpathHolder);
  						log.info("Applied thesaurus '" + t.getTitle() + "' to " + xpath);
  						count++;
  					}
  				}
  			}
  			result = "Applied thesaurus to " + count + " nodes";
  			log.info(result);
  		} catch(Exception e) {
  			log.info("Error applying thesaurus to current mapping: " + e.getMessage());
  			result = "Error";
  		}
  	}
  	
  	
  	private void saveThesaurus() {
  		try {
  			DataUpload du = DB.getDataUploadDAO().findById(Long.valueOf(uploadId), false);
  			Date now = new Date();
  			Thesaurus t = new Thesaurus();
  			t.setDescription(description);
  			t.setTitle(title);
  			t.setUploadDate(now);
  			t.setUrl(url);
  			t.setContactPerson(contact);
  			//find current user and set him as owner of this thesaurus
  			User u = getUser();
  			t.setOwner(u);
  			t.setOrganization(du.getOrganization());
  			if(uploadFile != null) {
  				log.info("Creating file: " + uploadFile.getName());
  				log.info("Original filename:" + filename);
  				FileInputStream fis = new FileInputStream( uploadFile );
  				BlobWrap data = new BlobWrap();
  				data.setData(Hibernate.createBlob(fis, (int) uploadFile.length()));
  				log.info("Created file: " + uploadFile.getName());
  				t.setFile(data);
  				t.setFilename(filename);
  				t.setContentType(contentType);
  			}
  			DB.getThesaurusDAO().makePersistent(t);			
  			result = t.getDbID().toString();
  			if(uploadFile != null) {
  				log.info("BlobWrapper id:" + t.getFile().getDbID());
  			}
  		} catch(Exception e) {
  			result = "Error";
  			log.info("Error saving thesaurus: " + e.getMessage());
  		}
  		
  	}
  	
  	private void editThesaurus() {
  		try {
  			Date now = new Date();
  			Thesaurus t = DB.getThesaurusDAO().findById(Long.valueOf(thesaurusId), false);
  			boolean access = hasAccess(t.getOrganization());
  			if((t != null) && access) {
  				t.setDescription(description);
  				t.setTitle(title);
  				t.setUploadDate(now);
  				t.setUrl(url);
  				t.setContactPerson(contact);
  				DB.getThesaurusDAO().makePersistent(t);
  				result = t.getDbID().toString();
  			} else {
  				result = "Couldn't update thesaurus";
  			}
  		} catch(Exception e) {
  			result = "Error";
  			log.info("Error saving thesaurus: " + e.getMessage());
  		}
  		
  	}
  	
  	private void thesaurusEditForm() {
  		try {
  