//create a version
if(pdvid==null)
pdvid = ""+UniqueKeyGenerator.issueProcessDefinitionVersionKey(tc);
ProcessDefinitionVersionRepositoryHomeLocal pdvhr;
ProcessDefinitionVersionRepositoryLocal pdvr = null;
pdvhr = GlobalContext.createProcessDefinitionVersionRepositoryHomeLocal(tc);
if(!overwrite){
if(version!=-1){
Collection existingVersions = pdvhr.findByDefinitionAndVersion(new Long(belongingPdid), new Long(version));
if(existingVersions.iterator().hasNext()){
pdvr = (ProcessDefinitionVersionRepositoryLocal)existingVersions.iterator().next();
pdvid = ""+pdvr.getDefVerId();
// throw new UEngineException("There is same version already exists. Choose another version.");
//FIXME: implement for non-ejb version.
if(!"org.uengine.kernel.DefaultProcessInstance".equals(GlobalContext.getPropertyString("processinstance.class"))){
ProcessInstanceDAOType pidaotype = ProcessInstanceDAOType.getInstance(tc);
ProcessInstanceDAO existingInstances = pidaotype.findByDefinitionVersion(pdvr.getDefVerId());
if(existingInstances.size()>0){
throw new UEngineException("There is some instances belonged to this definition already exists. Choose another version number.");
}
}
overwrite = true;
verifyModifiedDateWhenOverwriting = false;
}
}
if(pdvr==null){
pdvr = pdvhr.create(new Long(pdvid));
pdvr.setVer(new Long(version));
pdvr.setDefId(new Long(belongingPdid));
pdvr.setDefName(name);
}
}else{
pdvr = pdvhr.findByPrimaryKey(new Long(pdvid));
}
String fullFileName;
String relativeFileName;
if(overwrite){
removeFromCache(pdvid);
relativeFileName = pdvr.getFilePath().substring(LINK_SIGN.length());
int extPos = relativeFileName.lastIndexOf(".");
if(extPos == -1){
relativeFileName = relativeFileName + "_rev1";
}else{
int revPos = relativeFileName.indexOf("_rev");
int overWriteIndex = 0;
if(revPos != -1)
overWriteIndex = Integer.parseInt(relativeFileName.substring(revPos+4,extPos));
else
revPos = extPos;
overWriteIndex++;
relativeFileName = relativeFileName.substring(0, revPos) + "_rev" +overWriteIndex + relativeFileName.substring(extPos);
}
}else if(isAdhoc){
String calDir = UEngineUtil.getCalendarDir() + "/";
String dir = DEFINITION_ROOT + calDir;
(new File(dir)).mkdirs();
relativeFileName = calDir + pdvid + "." + objectType;
}else{
relativeFileName = pdvid + "." + objectType;
}
fullFileName = DEFINITION_ROOT + relativeFileName;
//store a binary version (to reduce serialization cost)
boolean isProcessDefinitionType=false;
if(definition instanceof String){
try{
if(GlobalContext.deserialize(definition.toString(), Object.class) instanceof ProcessDefinition){
isProcessDefinitionType=true;
}
}catch (Exception e) {
isProcessDefinitionType=false;
}
}else if(definition instanceof ProcessDefinition){
isProcessDefinitionType=true;
}
if(isProcessDefinitionType){
ProcessDefinition objectDefinition;
if(definition instanceof String){
ByteArrayInputStream bis = new ByteArrayInputStream(((String)definition).getBytes("UTF-8"));
try{
objectDefinition = getDefinition(bis);
}catch(Exception e){
throw new UEngineException("Error to parse definition: "+definition + " as Process Definition. Please check if the stream is not form of Process Definition.", e);
}
}else/* if(defintion instanceof ProcessDefinition)*/{
objectDefinition = (ProcessDefinition)definition;
}
//TODO: [performance] Definition in object form is here gotten. So it's no need to load again in the next transaction. Why not just put this in the cache?
//TODO: [disabled now]
// if(overwrite &&
// verifyModifiedDateWhenOverwriting &&
// objectDefinition.getModifiedDate()!=null && !objectDefinition.getModifiedDate().getTime().equals(pdvr.getModDate())
// )
// throw new UEngineException("This definition is modified by someone during you're editing.");
objectDefinition.setBelongingDefinitionId(belongingPdid);
objectDefinition.setId(pdvid);
objectDefinition.setVersion(version);
objectDefinition.setModifiedDate(modifiedDate);
String[] deployFilters = GlobalContext.getPropertyStringArray("deployfilters");
if(deployFilters!=null){
for(int i=0; i<deployFilters.length; i++){
try{
DeployFilter deployFilter = (DeployFilter)Class.forName(deployFilters[i]).newInstance();
deployFilter.beforeDeploy(objectDefinition, tc,folder,!definitionExist);
}catch(Exception e){
e.printStackTrace();
}
}
}
compileDefinition(fullFileName, objectDefinition);
if(options!=null && options.containsKey("associatedInstance")){
ProcessInstance instance = (ProcessInstance)options.get("associatedInstance");
instance.setProcessDefinition(objectDefinition);
}
if(definition instanceof String){
definition = GlobalContext.serialize(objectDefinition, String.class);
}
}
Timestamp timestamp = new Timestamp(modifiedDate.getTimeInMillis());
if(!DAOFactory.getInstance(tc).getDBMSProductName().startsWith("DB2"))
pdvr.setModDate(timestamp);
//store definition as XML-Bean text file
//if(version!=-1){ //only when the definition is adhoc instance //changed to alwalys
String strDef;
if(definition instanceof String){
strDef = (String)definition;
}else{
ByteArrayOutputStream bao = new ByteArrayOutputStream();
GlobalContext.serialize((ProcessDefinition)definition, bao, String.class);
strDef = bao.toString("UTF-8");
}
OutputStreamWriter bw = null;
try{
bw = new OutputStreamWriter(new FileOutputStream(fullFileName), "UTF-8");
bw.write(strDef);
bw.close();
}catch(Exception e){
throw e;
}finally{
if(bw!=null)
try{bw.close();}catch(Exception e){};
}
//}
//verify consistency with referencing instances /////////////////// --> disabled
/* if(overwrite && options!=null){
String instanceId = (options.containsKey("instanceId") ? (String)options.get("instanceId") : null);
if(instanceId!=null){
ProcessInstance instance = ProcessInstance.create().getInstance(instanceId);
Vector runningActivityTracingTags = instance.getRunningOrCompletedActivityTracingTags();
for(int i=0; i<runningActivityTracingTags.size(); i++){
String tracingTagToVerify = (String)runningActivityTracingTags.elementAt(i);
Activity activityNew = objectDefinition.getActivity(tracingTagToVerify);
if(activityNew == null){
throw new UEngineException("The changed definition is not consistent with running instance. REASON: Though activity with tracingtag '" + tracingTagToVerify + "' is already running or completed, it is ommitted in the changed process.");
}
}
}
}*/
//if(!overwrite){
pdvr.setFilePath(LINK_SIGN + relativeFileName);
//}
return new String[]{pdvid, belongingPdid, LINK_SIGN + relativeFileName};
}