package org.fireflow.engine.modules.persistence.nutz; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.fireflow.engine.context.RuntimeContext; import org.fireflow.engine.entity.repository.ProcessDescriptor; import org.fireflow.engine.entity.repository.ProcessDescriptorProperty; import org.fireflow.engine.entity.repository.ProcessKey; import org.fireflow.engine.entity.repository.ProcessRepository; import org.fireflow.engine.entity.repository.impl.ProcessDescriptorImpl; import org.fireflow.engine.entity.repository.impl.ProcessRepositoryImpl; import org.fireflow.engine.modules.persistence.ProcessPersister; import org.fireflow.engine.modules.processlanguage.ProcessLanguageManager; import org.fireflow.model.InvalidModelException; import org.firesoa.common.util.Utils; import org.nutz.dao.Cnd; import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; public class ProcessPersisterNutzImpl extends AbsPersisterNutzImpl implements ProcessPersister { private static final Log log = LogFactory.getLog(ProcessPersisterNutzImpl.class); //TODO 下面这个Cache是否需要,待研究…… // process相关的信息实际上已经缓存在KernelManager中了,应该无需保留,此cache机制待删除掉,2013-04-24 Map<ProcessKey,ProcessRepository> cache = new HashMap<ProcessKey,ProcessRepository>(); private boolean useProcessCache = false; public boolean isUseProcessCache(){ return useProcessCache; } public void setUseProcessCache(boolean b){ this.useProcessCache = b; } public void deleteAllProcesses() { dao().clear(ProcessDescriptorImpl.class); } public ProcessRepository persistProcessToRepository(String processXml, ProcessDescriptor descriptor) { ProcessRepositoryImpl repository = (ProcessRepositoryImpl)descriptor.toProcessRepository(); repository.setProcessContent(processXml); //表示插入操作,需要重新生成version字段 if (repository.getVersion()==null || repository.getVersion()<=0){ int v = this.findTheLatestVersion(repository.getProcessId(), repository.getProcessType()); repository.setVersion(v+1); } this.saveOrUpdate(repository); //缓存 if (useProcessCache){ this.cache(repository); } return repository; } public ProcessRepository findProcessRepositoryByProcessKey( ProcessKey processKey) throws InvalidModelException { Cnd cnd = Cnd .where(ProcessDescriptorProperty.PROCESS_ID.getPropertyName(), "=", processKey.getProcessId()) .and(ProcessDescriptorProperty.PROCESS_TYPE.getPropertyName(), "=", processKey.getProcessType()) .and(ProcessDescriptorProperty.VERSION.getPropertyName(), "=", processKey.getVersion()); ProcessRepository repository = this.getFromCache(processKey); if (repository != null) { return repository; } repository = dao() .fetch(ProcessRepositoryImpl.class, cnd); if (repository != null) { try{ RuntimeContext ctx = this.getPersistenceService().getRuntimeContext(); ProcessLanguageManager processUtil = ctx.getEngineModule(ProcessLanguageManager.class, processKey.getProcessType()); String xml = repository.getProcessContent(); String encoding = Utils.findXmlCharset(xml); ByteArrayInputStream inStream = new ByteArrayInputStream(xml.getBytes(encoding)); Object obj = processUtil.deserializeXml2Process(inStream); ((ProcessRepositoryImpl)repository).setProcessObject(obj); //TODO // repository.getFileName() 与 WorkflowProcess.getClasspathUri()的设置关系如何处理? }catch(UnsupportedEncodingException e){ log.error(e); } } return (ProcessRepository) repository; } public ProcessRepository findTheLatestVersionOfProcessRepository( String processId, String processType) throws InvalidModelException { int v = this.findTheLatestVersion(processId,processType) ; if (v==0){ return null; }else{ ProcessKey processKey = new ProcessKey(processId,v,processType); ProcessRepository repository = this.getFromCache(processKey); if (repository!=null) { return repository; }else{ return this.findProcessRepositoryByProcessKey(new ProcessKey(processId,v,processType)); } } } public String findProcessXml(ProcessKey processKey) { ProcessRepository repository; try { repository = this.findProcessRepositoryByProcessKey(processKey); if (repository==null)return ""; return repository.getProcessContent(); } catch (InvalidModelException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ""; } public ProcessDescriptor findProcessDescriptorByProcessKey( ProcessKey processKey) { Cnd cnd = Cnd.where(ProcessDescriptorProperty.PROCESS_ID.getPropertyName(), "=", processKey.getProcessId()) .and(ProcessDescriptorProperty.PROCESS_TYPE.getPropertyName(),"=",processKey.getProcessType()) .and(ProcessDescriptorProperty.VERSION.getPropertyName(),"=",processKey.getVersion()); ProcessRepository repository = this.getFromCache(processKey); if (repository!=null) { return repository; } ProcessDescriptor result = dao().fetch(ProcessDescriptorImpl.class, cnd); return (ProcessDescriptor)result; } public ProcessDescriptor findTheLatestVersionOfProcessDescriptor( String processId, String processType) { int v = this.findTheLatestVersion(processId,processType) ; if (v==0){ return null; }else{ ProcessKey processKey = new ProcessKey(processId,v,processType); ProcessRepository repository = this.getFromCache(processKey); if (repository!=null) { return repository; }else{ return this.findProcessDescriptorByProcessKey(new ProcessKey(processId,v,processType)); } } } public int findTheLatestVersion(String processId, String processType) { Sql sql = Sqls.create("SELECT max(VERSION) FROM T_FF_DF_PROCESS_REPOSITORY WHERE PROCESS_ID=@processId and PROCESS_TYPE=@processType"); sql.params().set("processId", processId); sql.params().set("processType", processType); sql.setCallback(Sqls.callback.integer()); dao().execute(sql); try{ int result = sql.getInt(); return result; }catch(NullPointerException e){ return 0; } } public int findTheLatestPublishedVersion(String processId, String processType) { Sql sql = Sqls.create("SELECT max(VERSION) FROM T_FF_DF_PROCESS_REPOSITORY WHERE PROCESS_ID=@processId and PROCESS_TYPE=@processType and PUBLISH_STATE=@publishState"); sql.params().set("processId", processId); sql.params().set("processType", processType); sql.params().set("publishState", Boolean.TRUE); sql.setCallback(Sqls.callback.integer()); dao().execute(sql); try{ int result = sql.getInt(); return result; }catch(NullPointerException e){ return 0; } } @SuppressWarnings("unchecked") public Class getEntityClass4Runtime(Class interfaceClz){ if (interfaceClz.isAssignableFrom(ProcessDescriptor.class)){ return ProcessDescriptorImpl.class; }else if (interfaceClz.isAssignableFrom(ProcessRepository.class)){ return ProcessRepositoryImpl.class; } return null; } protected ProcessRepository getFromCache(ProcessKey key){ if (this.isUseProcessCache()){ return this.cache.get(key); } return null; } protected void cache(ProcessRepository processRepository){ if (this.isUseProcessCache()) { ProcessKey pk = new ProcessKey(processRepository.getProcessId(), processRepository.getVersion(), processRepository .getProcessType()); this.cache.put(pk, processRepository); } } }