package org.aplikator.server.data;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.aplikator.client.shared.data.FunctionParameters;
import org.aplikator.client.shared.data.FunctionResult;
import org.aplikator.client.shared.data.ItemSuggestion;
import org.aplikator.client.shared.data.ListItem;
import org.aplikator.client.shared.data.PrimaryKey;
import org.aplikator.client.shared.data.RecordContainerDTO;
import org.aplikator.client.shared.data.RecordDTO;
import org.aplikator.client.shared.data.SearchResult;
import org.aplikator.client.shared.descriptor.ApplicationDTO;
import org.aplikator.client.shared.descriptor.FunctionDTO;
import org.aplikator.client.shared.descriptor.ProcessDTO;
import org.aplikator.client.shared.descriptor.QueryDescriptorDTO;
import org.aplikator.client.shared.descriptor.QueryParameterDTO;
import org.aplikator.client.shared.descriptor.RecordsPageDTO;
import org.aplikator.client.shared.descriptor.SuggestionsDTO;
import org.aplikator.client.shared.descriptor.ViewDTO;
import org.aplikator.client.shared.descriptor.WizardPageDTO;
import org.aplikator.client.shared.rpc.AplikatorService;
import org.aplikator.server.DescriptorRegistry;
import org.aplikator.server.ListRegistry;
import org.aplikator.server.descriptor.*;
import org.aplikator.server.persistence.Persister;
import org.aplikator.server.persistence.PersisterFactory;
import org.aplikator.server.persistence.search.SearchFactory;
import org.aplikator.server.processes.CannotCallStopException;
import org.aplikator.server.processes.Process;
import org.aplikator.server.processes.ProcessManager;
import org.aplikator.server.query.QueryExpression;
import org.jboss.errai.bus.server.annotations.Service;
/**
* The server side implementation of the RPC service.
*/
@Service
public class AplikatorServiceImpl implements AplikatorService {
private static final Logger LOG = Logger.getLogger(AplikatorServiceImpl.class.getName());
@javax.ws.rs.core.Context
HttpServletRequest httpServletRequest;
@javax.ws.rs.core.Context
HttpServletResponse httpServletResponse;
private AplikatorServiceBackend aplikatorServiceBackend = new AplikatorServiceBackend();
private Persister persister = PersisterFactory.getPersister();
//@Override
public Context ctx(RecordContainer rc) {
return new Context(httpServletRequest, httpServletResponse, aplikatorServiceBackend, rc);
}
//@Override
public Context ctx() {
return new Context(httpServletRequest, httpServletResponse, aplikatorServiceBackend, null);
}
public void login(String principal, String password) {
Context ctx = ctx();
try {
Subject currentUser = SecurityUtils.getSubject();
currentUser.login(new UsernamePasswordToken(principal, password));
Application.get().onLogin(currentUser.getPrincipal(), ctx);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in login: " + t.getMessage(), t);
throw new RuntimeException("Error in login: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
public void logout() {
Context ctx = ctx();
try {
Subject currentUser = SecurityUtils.getSubject();
currentUser.logout();
Application.get().onLogout(currentUser.getPrincipal(), ctx);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in logout: " + t.getMessage(), t);
throw new RuntimeException("Error in logout: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public ApplicationDTO getApplication() {
Context ctx = ctx();
try {
return Application.get().getApplicationDTO(ctx);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getApplication: " + t.getMessage(), t);
throw new RuntimeException("Error in getApplication: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public List<ListItem> getList(String listName) {
Context ctx = ctx();
try {
ListProvider listProvider = ListRegistry.get().getListProvider(listName);
if (listProvider != null) {
return listProvider.getListValues(ctx);
}
return null;
} finally {
ctx.closeTransaction();
}
}
@Override
public ViewDTO getView(String id) {
Context ctx = ctx();
try {
View view = (View) DescriptorRegistry.get().getDescriptionItem(id);
return view.getViewDTO(ctx);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getView: " + t.getMessage(), t);
throw new RuntimeException("Error in getView: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public RecordContainerDTO processRecords(RecordContainerDTO recordContainerDTO) {
RecordContainer recordContainer = new RecordContainer(recordContainerDTO);
Context ctx = ctx(recordContainer);
try {
return aplikatorServiceBackend.processRecords(recordContainer, ctx).getRecordContainerDTO();
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in processRecords: " + t.getMessage(), t);
throw new RuntimeException("Error in processRecords: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
@SuppressWarnings("unchecked")
public SuggestionsDTO getSuggestions(String viewid, String activeSort, String searchString) {
Context ctx = ctx();
try {
View view = (View) DescriptorRegistry.get().getDescriptionItem(viewid);
SortDescriptor activeSortDescriptor = view.getSortDescriptor(activeSort);
Property primarySortProperty = activeSortDescriptor.getPrimarySortProperty();
SortItem[] sortItems = activeSortDescriptor.getItems().toArray(new SortItem[activeSortDescriptor.getItems().size()]);
List<Record> records = persister.getRecords(view, null, sortItems, searchString, null, null, 0, view.getPageSize(), ctx);
List<ItemSuggestion> suggestions = new ArrayList<ItemSuggestion>(records.size());
for (Record rec : records) {
int pk = rec.getPrimaryKey().getId();
Object val = rec.getValue(primarySortProperty);
String repl = val != null ? val.toString() : "";
suggestions.add(new ItemSuggestion(rec.getPreview(), pk, repl, rec.getRecordDTO()));
}
SuggestionsDTO sug = new SuggestionsDTO();
sug.setSuggestions(suggestions);
return sug;
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getSuggestions: " + t.getMessage(), t);
throw new RuntimeException("Error in getSuggestions: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public RecordDTO getRecord(String primaryKey, String viewId) {
Context ctx = ctx();
try {
View view = (View) DescriptorRegistry.get().getDescriptionItem(viewId);
return aplikatorServiceBackend.getRecord(new PrimaryKey(primaryKey), view, ctx).getRecordDTO();
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getRecord: " + t.getMessage(), t);
throw new RuntimeException("Error in getRecord: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public RecordsPageDTO getRecords(String viewId, String activeFilter, String activeSort, QueryDescriptorDTO queryDescriptor, String searchString, String ownerPropertyId, String ownerPrimaryKey, int pageOffset, int pageSize) {
Context ctx = ctx();
try {
RecordsPageDTO page = new RecordsPageDTO();
Collection ownerProperty = null;
if (ownerPropertyId != null && !"".equals(ownerPropertyId)) {
ownerProperty = (Collection) DescriptorRegistry.get().getDescriptionItem(ownerPropertyId);
}
View view = (View) DescriptorRegistry.get().getDescriptionItem(viewId);
List<QueryParameter> queryParameters = new ArrayList<QueryParameter>(queryDescriptor.getQueryParameters().size());
for (QueryParameterDTO queryParameterDTO : queryDescriptor.getQueryParameters()) {
queryParameters.add(new QueryParameter(queryParameterDTO));
}
QueryExpression queryExpression = view.getQueryDescriptor(activeFilter).getQueryExpression(queryParameters, ctx);
SortItem[] sortItems = null;
if (activeSort != null && !activeSort.equals("")) {
SortDescriptor sortDescriptor = view.getSortDescriptor(activeSort);
sortItems = sortDescriptor.getItems().toArray(new SortItem[sortDescriptor.getItems().size()]);
}
List<Record> loadedRecords = persister.getRecords(view, queryExpression, sortItems, searchString, ownerProperty, (ownerPrimaryKey == null || ownerPrimaryKey.trim().length() == 0) ? null : new PrimaryKey(ownerPrimaryKey), pageOffset, pageSize, ctx);
List<RecordDTO> dtos = new ArrayList<RecordDTO>(loadedRecords.size());
for (Record loadedRecord : loadedRecords) {
dtos.add(loadedRecord.getRecordDTO());
}
page.setRecords(dtos);
page.setOffset(pageOffset);
return page;
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getPage: " + t.getMessage(), t);
throw new RuntimeException("Error in getPage: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public SearchResult getPageSearch(String viewId, String searchArgument, int pageOffset, int pageSize) {
Context ctx = ctx();
try {
return SearchFactory.get().getPagefromSearch(viewId, searchArgument, pageOffset, pageSize, ctx);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getPageSearch: " + t.getMessage(), t);
throw new RuntimeException("Error in getPageSearch: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public int getRecordCount(String viewId, String activeFilter, String activeSort, QueryDescriptorDTO queryDescriptor, String searchString, String ownerPropertyId, String ownerPrimaryKeyString) {
Context ctx = ctx();
try {
Collection ownerProperty = null;
PrimaryKey ownerPrimaryKey = null;
if (ownerPropertyId != null && !"".equals(ownerPropertyId)) {
ownerProperty = (Collection) DescriptorRegistry.get().getDescriptionItem(ownerPropertyId);
ownerPrimaryKey = (ownerPrimaryKeyString == null || ownerPrimaryKeyString.trim().length() == 0) ? null : new PrimaryKey(ownerPrimaryKeyString);
}
View view = (View) DescriptorRegistry.get().getDescriptionItem(viewId);
List<QueryParameter> queryParameters = new ArrayList<QueryParameter>(queryDescriptor.getQueryParameters().size());
for (QueryParameterDTO queryParameterDTO : queryDescriptor.getQueryParameters()) {
queryParameters.add(new QueryParameter(queryParameterDTO));
}
QueryExpression queryExpression = view.getQueryDescriptor(activeFilter).getQueryExpression(queryParameters, ctx);
SortItem[] sortItems = null;
if (activeSort != null && !activeSort.equals("")) {
SortDescriptor sortDescriptor = view.getSortDescriptor(activeSort);
sortItems = sortDescriptor.getItems().toArray(new SortItem[sortDescriptor.getItems().size()]);
}
return aplikatorServiceBackend.getRecordCount(view, queryExpression, sortItems, searchString, ownerProperty, ownerPrimaryKey, ctx);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getRecordCount: " + t.getMessage(), t);
throw new RuntimeException("Error in getRecordCount: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public FunctionResult runFunction(FunctionParameters functionParameters) {
aplikatorServiceBackend.checkSuspendedState();
Context ctx = ctx();
try {
Function func = (Function) DescriptorRegistry.get().getDescriptionItem(functionParameters.getFunctionId());
FunctionResult result = func.getExecutable().execute(new Record(functionParameters.getClientContext().getCurrentRecord()),
new Record(functionParameters.getClientParameters()),
functionParameters.getClientContext(), ctx);
return result;
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in runFunction: " + t.getMessage(), t);
throw new RuntimeException("Error in runFunction: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public FunctionDTO getFunction(String id) {
Context ctx = ctx();
try {
Function function = (Function) DescriptorRegistry.get().getDescriptionItem(id);
return function.getFunctionDTO(ctx);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getFunction: " + t.getMessage(), t);
throw new RuntimeException("Error in getFunction: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public WizardPageDTO getWizardPage(String curPage, boolean forwardFlag, FunctionParameters functionParameters) {
aplikatorServiceBackend.checkSuspendedState();
Context ctx = ctx();
try {
Function func = (Function) DescriptorRegistry.get().getDescriptionItem(functionParameters.getFunctionId());
Record record = new Record(functionParameters.getClientContext().getCurrentRecord());
Record clientRecordProperties = new Record(functionParameters.getClientParameters());
WizardPage wizPage = func.getExecutable().getWizardPage(curPage, forwardFlag, record, clientRecordProperties, functionParameters.getClientContext(), ctx);
return wizPage == null ? null : wizPage.getViewDTO(ctx);
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getWizardPage: " + t.getMessage(), t);
throw new RuntimeException("Error in getWizardPage: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public RecordDTO getCompleteRecord(String primaryKey, int traverseLevel, boolean includeCollections) {
Context ctx = ctx();
try {
Record completeRecord = aplikatorServiceBackend.getCompleteRecord(primaryKey, traverseLevel, includeCollections, ctx);
return completeRecord.getRecordDTO();
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getCompleteRecord: " + t.getMessage(), t);
throw new RuntimeException("Error in getCompleteRecord: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public RecordContainerDTO prepareRecord(String primaryKey, String viewId, String ownerPropertyId, String ownerPrimaryKey) {
Context ctx = ctx();
try {
PrimaryKey pk = null;
if (primaryKey != null && !"".equals(primaryKey)) {
pk = new PrimaryKey(primaryKey);
}
View view = (View) DescriptorRegistry.get().getDescriptionItem(viewId);
Collection ownerProperty = null;
PrimaryKey ownerPK = null;
if (ownerPropertyId != null && !"".equals(ownerPropertyId)) {
ownerProperty = (Collection) DescriptorRegistry.get().getDescriptionItem(ownerPropertyId);
ownerPK = new PrimaryKey(ownerPrimaryKey);
}
return aplikatorServiceBackend.prepareRecord(pk, view, ownerProperty, ownerPK, ctx).getRecordContainerDTO();
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in prepareRecord: " + t.getMessage(), t);
throw new RuntimeException("Error in prepareRecord: " + t.getMessage(), t);
} finally {
ctx.closeTransaction();
}
}
@Override
public List<ProcessDTO> getProcesses() {
try {
ProcessManager pm = ProcessManager.getManager();
List<Process> prs = pm.getProcesses();
List<ProcessDTO> pdtos = new ArrayList<ProcessDTO>();
for (Process ps : prs) {
pdtos.add(ps.toProcessDTO());
}
return pdtos;
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getProcesses: " + t.getMessage(), t);
throw new RuntimeException("Error in getProcesses: " + t.getMessage(), t);
}
}
@Override
public ProcessDTO getProcess(String procId) {
try {
ProcessManager pm = ProcessManager.getManager();
Process p = pm.lookUpProcess(procId);
return p != null ? p.toProcessDTO() : null;
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in getProcess: " + t.getMessage(), t);
throw new RuntimeException("Error in getProcess: " + t.getMessage(), t);
}
}
@Override
public ProcessDTO stopProcess(String procId, String stop) {
try {
ProcessManager pm = ProcessManager.getManager();
Process p = pm.lookUpProcess(procId);
if (p != null) {
try {
p.stopMe();
} catch (CannotCallStopException ex) {
Logger.getLogger(AplikatorServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
}
return p.toProcessDTO();
} else {
return null;
}
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in stopProcess: " + t.getMessage(), t);
throw new RuntimeException("Error in stopProcess: " + t.getMessage(), t);
}
}
@Override
public ProcessDTO deleteProcess(String procId) {
try {
ProcessManager pm = ProcessManager.getManager();
Process p = pm.lookUpProcess(procId);
pm.deregisterProcess(p);
return p.toProcessDTO();
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Error in deleteProcess: " + t.getMessage(), t);
throw new RuntimeException("Error in deleteProcess: " + t.getMessage(), t);
}
}
@Override
public boolean isSuspended() {
return persister.isSuspended();
}
@Override
public boolean setSuspended(boolean suspended) {
return persister.setSuspended(suspended);
}
}