/*
* Copyright 2015 - 2017 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.server.api.marshalling.jaxb;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.drools.core.command.GetVariableCommand;
import org.drools.core.command.runtime.AdvanceSessionTimeCommand;
import org.drools.core.command.runtime.BatchExecutionCommandImpl;
import org.drools.core.command.runtime.GetFactCountCommand;
import org.drools.core.command.runtime.GetGlobalCommand;
import org.drools.core.command.runtime.GetIdCommand;
import org.drools.core.command.runtime.GetSessionTimeCommand;
import org.drools.core.command.runtime.SetGlobalCommand;
import org.drools.core.command.runtime.rule.AgendaGroupSetFocusCommand;
import org.drools.core.command.runtime.rule.ClearActivationGroupCommand;
import org.drools.core.command.runtime.rule.ClearAgendaCommand;
import org.drools.core.command.runtime.rule.ClearAgendaGroupCommand;
import org.drools.core.command.runtime.rule.ClearRuleFlowGroupCommand;
import org.drools.core.command.runtime.rule.DeleteCommand;
import org.drools.core.command.runtime.rule.FireAllRulesCommand;
import org.drools.core.command.runtime.rule.GetFactHandlesCommand;
import org.drools.core.command.runtime.rule.InsertObjectCommand;
import org.drools.core.command.runtime.rule.UpdateCommand;
import org.drools.core.common.DefaultFactHandle;
import org.drools.core.runtime.impl.ExecutionResultImpl;
import org.drools.core.runtime.rule.impl.FlatQueryResults;
import org.kie.server.api.commands.CallContainerCommand;
import org.kie.server.api.commands.CommandScript;
import org.kie.server.api.commands.CreateContainerCommand;
import org.kie.server.api.commands.DescriptorCommand;
import org.kie.server.api.commands.DisposeContainerCommand;
import org.kie.server.api.commands.GetContainerInfoCommand;
import org.kie.server.api.commands.GetReleaseIdCommand;
import org.kie.server.api.commands.GetScannerInfoCommand;
import org.kie.server.api.commands.GetServerInfoCommand;
import org.kie.server.api.commands.GetServerStateCommand;
import org.kie.server.api.commands.ListContainersCommand;
import org.kie.server.api.commands.UpdateReleaseIdCommand;
import org.kie.server.api.commands.UpdateScannerCommand;
import org.kie.server.api.commands.optaplanner.CreateSolverCommand;
import org.kie.server.api.commands.optaplanner.DisposeSolverCommand;
import org.kie.server.api.commands.optaplanner.GetSolverWithBestSolutionCommand;
import org.kie.server.api.commands.optaplanner.GetSolverCommand;
import org.kie.server.api.commands.optaplanner.GetSolversCommand;
import org.kie.server.api.commands.optaplanner.SolvePlanningProblemCommand;
import org.kie.server.api.commands.optaplanner.TerminateSolverEarlyCommand;
import org.kie.server.api.marshalling.Marshaller;
import org.kie.server.api.marshalling.MarshallingException;
import org.kie.server.api.marshalling.MarshallingFormat;
import org.kie.server.api.marshalling.ModelWrapper;
import org.kie.server.api.model.KieContainerResource;
import org.kie.server.api.model.KieContainerResourceFilter;
import org.kie.server.api.model.KieContainerResourceList;
import org.kie.server.api.model.KieContainerStatus;
import org.kie.server.api.model.KieContainerStatusFilter;
import org.kie.server.api.model.KieServerConfig;
import org.kie.server.api.model.KieServerConfigItem;
import org.kie.server.api.model.KieServerInfo;
import org.kie.server.api.model.KieServerStateInfo;
import org.kie.server.api.model.Message;
import org.kie.server.api.model.ReleaseId;
import org.kie.server.api.model.ReleaseIdFilter;
import org.kie.server.api.model.ServiceResponse;
import org.kie.server.api.model.ServiceResponsesList;
import org.kie.server.api.model.admin.EmailNotification;
import org.kie.server.api.model.admin.ExecutionErrorInstance;
import org.kie.server.api.model.admin.ExecutionErrorInstanceList;
import org.kie.server.api.model.admin.MigrationReportInstance;
import org.kie.server.api.model.admin.MigrationReportInstanceList;
import org.kie.server.api.model.admin.OrgEntities;
import org.kie.server.api.model.admin.ProcessNode;
import org.kie.server.api.model.admin.ProcessNodeList;
import org.kie.server.api.model.admin.TaskNotification;
import org.kie.server.api.model.admin.TaskNotificationList;
import org.kie.server.api.model.admin.TaskReassignment;
import org.kie.server.api.model.admin.TaskReassignmentList;
import org.kie.server.api.model.admin.TimerInstance;
import org.kie.server.api.model.admin.TimerInstanceList;
import org.kie.server.api.model.cases.CaseAdHocFragment;
import org.kie.server.api.model.cases.CaseAdHocFragmentList;
import org.kie.server.api.model.cases.CaseComment;
import org.kie.server.api.model.cases.CaseCommentList;
import org.kie.server.api.model.cases.CaseDefinition;
import org.kie.server.api.model.cases.CaseDefinitionList;
import org.kie.server.api.model.cases.CaseFile;
import org.kie.server.api.model.cases.CaseFileDataItem;
import org.kie.server.api.model.cases.CaseFileDataItemList;
import org.kie.server.api.model.cases.CaseInstance;
import org.kie.server.api.model.cases.CaseInstanceList;
import org.kie.server.api.model.cases.CaseMilestone;
import org.kie.server.api.model.cases.CaseMilestoneDefinition;
import org.kie.server.api.model.cases.CaseMilestoneList;
import org.kie.server.api.model.cases.CaseRoleAssignment;
import org.kie.server.api.model.cases.CaseRoleAssignmentList;
import org.kie.server.api.model.cases.CaseStage;
import org.kie.server.api.model.cases.CaseStageDefinition;
import org.kie.server.api.model.cases.CaseStageList;
import org.kie.server.api.model.definition.ProcessDefinition;
import org.kie.server.api.model.definition.ProcessDefinitionList;
import org.kie.server.api.model.definition.QueryDefinition;
import org.kie.server.api.model.definition.QueryDefinitionList;
import org.kie.server.api.model.definition.QueryFilterSpec;
import org.kie.server.api.model.definition.QueryParam;
import org.kie.server.api.model.dmn.DMNContextKS;
import org.kie.server.api.model.dmn.DMNDecisionInfo;
import org.kie.server.api.model.dmn.DMNDecisionResultKS;
import org.kie.server.api.model.dmn.DMNMessageKS;
import org.kie.server.api.model.dmn.DMNModelInfo;
import org.kie.server.api.model.dmn.DMNModelInfoList;
import org.kie.server.api.model.dmn.DMNNodeStub;
import org.kie.server.api.model.dmn.DMNResultKS;
import org.kie.server.api.model.instance.DocumentInstance;
import org.kie.server.api.model.instance.DocumentInstanceList;
import org.kie.server.api.model.instance.ErrorInfoInstance;
import org.kie.server.api.model.instance.ErrorInfoInstanceList;
import org.kie.server.api.model.instance.JobRequestInstance;
import org.kie.server.api.model.instance.NodeInstance;
import org.kie.server.api.model.instance.NodeInstanceList;
import org.kie.server.api.model.instance.ProcessInstance;
import org.kie.server.api.model.instance.ProcessInstanceList;
import org.kie.server.api.model.instance.RequestInfoInstance;
import org.kie.server.api.model.instance.RequestInfoInstanceList;
import org.kie.server.api.model.instance.ScoreWrapper;
import org.kie.server.api.model.instance.SolverInstance;
import org.kie.server.api.model.instance.SolverInstanceList;
import org.kie.server.api.model.instance.TaskAttachment;
import org.kie.server.api.model.instance.TaskAttachmentList;
import org.kie.server.api.model.instance.TaskComment;
import org.kie.server.api.model.instance.TaskCommentList;
import org.kie.server.api.model.instance.TaskEventInstance;
import org.kie.server.api.model.instance.TaskEventInstanceList;
import org.kie.server.api.model.instance.TaskInstance;
import org.kie.server.api.model.instance.TaskInstanceList;
import org.kie.server.api.model.instance.TaskSummary;
import org.kie.server.api.model.instance.TaskSummaryList;
import org.kie.server.api.model.instance.VariableInstance;
import org.kie.server.api.model.instance.VariableInstanceList;
import org.kie.server.api.model.instance.WorkItemInstance;
import org.kie.server.api.model.instance.WorkItemInstanceList;
import org.kie.server.api.model.type.JaxbByteArray;
import org.kie.server.api.model.type.JaxbDate;
import org.kie.server.api.model.type.JaxbList;
import org.kie.server.api.model.type.JaxbMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JaxbMarshaller implements Marshaller {
private static final Logger logger = LoggerFactory.getLogger(JaxbMarshaller.class);
public static final Class<?>[] KIE_SERVER_JAXB_CLASSES;
static {
KIE_SERVER_JAXB_CLASSES = new Class<?>[]{
CallContainerCommand.class,
CommandScript.class,
CreateContainerCommand.class,
DisposeContainerCommand.class,
ListContainersCommand.class,
GetContainerInfoCommand.class,
GetScannerInfoCommand.class,
GetServerInfoCommand.class,
UpdateScannerCommand.class,
GetReleaseIdCommand.class,
UpdateReleaseIdCommand.class,
DescriptorCommand.class,
GetServerStateCommand.class,
KieContainerResource.class,
KieContainerResourceList.class,
KieContainerStatus.class,
KieServerInfo.class,
ReleaseId.class,
ServiceResponse.class,
ServiceResponsesList.class,
KieServerStateInfo.class,
ReleaseIdFilter.class,
KieContainerStatusFilter.class,
KieContainerResourceFilter.class,
BatchExecutionCommandImpl.class,
ExecutionResultImpl.class,
DefaultFactHandle.class,
DeleteCommand.class,
GetVariableCommand.class,
GetFactCountCommand.class,
SetGlobalCommand.class,
UpdateCommand.class,
ClearAgendaCommand.class,
FireAllRulesCommand.class,
GetIdCommand.class,
GetGlobalCommand.class,
InsertObjectCommand.class,
ClearAgendaGroupCommand.class,
FlatQueryResults.class,
AgendaGroupSetFocusCommand.class,
ClearRuleFlowGroupCommand.class,
ClearActivationGroupCommand.class,
GetFactHandlesCommand.class,
GetSessionTimeCommand.class,
AdvanceSessionTimeCommand.class,
KieServerConfig.class,
KieServerConfigItem.class,
JaxbList.class,
JaxbMap.class,
JaxbDate.class,
JaxbByteArray.class,
JaxbByteArray.class,
ProcessDefinition.class,
ProcessDefinitionList.class,
ProcessInstance.class,
ProcessInstanceList.class,
NodeInstance.class,
NodeInstanceList.class,
VariableInstance.class,
VariableInstanceList.class,
TaskInstance.class,
TaskInstanceList.class,
TaskSummary.class,
TaskSummaryList.class,
TaskEventInstance.class,
TaskEventInstanceList.class,
TaskComment.class,
TaskCommentList.class,
TaskAttachment.class,
TaskAttachmentList.class,
WorkItemInstance.class,
WorkItemInstanceList.class,
RequestInfoInstance.class,
RequestInfoInstanceList.class,
ErrorInfoInstance.class,
ErrorInfoInstanceList.class,
JobRequestInstance.class,
DocumentInstance.class,
DocumentInstanceList.class,
QueryDefinition.class,
QueryDefinitionList.class,
QueryFilterSpec.class,
QueryParam.class,
ArrayList.class,
// OptaPlanner
SolverInstance.class,
SolverInstanceList.class,
Message.class,
ScoreWrapper.class,
// Optaplanner commands
CreateSolverCommand.class,
DisposeSolverCommand.class,
GetSolverWithBestSolutionCommand.class,
GetSolversCommand.class,
GetSolverCommand.class,
SolvePlanningProblemCommand.class,
TerminateSolverEarlyCommand.class,
// admin section
MigrationReportInstance.class,
MigrationReportInstanceList.class,
ProcessNode.class,
ProcessNodeList.class,
TimerInstance.class,
TimerInstanceList.class,
EmailNotification.class,
OrgEntities.class,
TaskNotification.class,
TaskNotificationList.class,
TaskReassignment.class,
TaskReassignmentList.class,
ExecutionErrorInstance.class,
ExecutionErrorInstanceList.class,
// case management
CaseMilestone.class,
CaseMilestoneList.class,
CaseInstance.class,
CaseInstanceList.class,
CaseFile.class,
CaseStage.class,
CaseStageList.class,
CaseAdHocFragment.class,
CaseAdHocFragmentList.class,
CaseComment.class,
CaseCommentList.class,
CaseRoleAssignment.class,
CaseRoleAssignmentList.class,
CaseDefinition.class,
CaseDefinitionList.class,
CaseMilestoneDefinition.class,
CaseStageDefinition.class,
CaseFileDataItem.class,
CaseFileDataItemList.class,
// Kie DMN
DMNContextKS.class,
DMNResultKS.class,
DMNNodeStub.class,
DMNMessageKS.class,
DMNDecisionResultKS.class,
DMNModelInfoList.class,
DMNModelInfo.class,
DMNDecisionInfo.class
};
}
protected JAXBContext jaxbContext;
protected ClassLoader classLoader;
public JaxbMarshaller(Set<Class<?>> classes, ClassLoader classLoader) {
this.classLoader = classLoader;
buildMarshaller(classes, classLoader);
}
protected void buildMarshaller( Set<Class<?>> classes, final ClassLoader classLoader ) {
try {
logger.debug("Additional classes for JAXB context are {}", classes);
Set<Class<?>> allClasses = new HashSet<Class<?>>();
allClasses.addAll(Arrays.asList(KIE_SERVER_JAXB_CLASSES));
if (classes != null) {
allClasses.addAll(classes);
}
logger.debug("All classes for JAXB context are {}", allClasses);
this.jaxbContext = JAXBContext.newInstance( allClasses.toArray(new Class[allClasses.size()]) );
} catch ( JAXBException e ) {
logger.error("Error while creating JAXB Marshaller due to {}", e.getMessage(), e);
throw new MarshallingException( "Error while creating JAXB context from default classes! " + e.getMessage(), e );
}
}
protected void configureMarshaller( Set<Class<?>> classes, final ClassLoader classLoader ) {
// by default nothing to configure though it might be needed in case of extensions
}
@Override
public String marshall(Object input) {
StringWriter writer = new StringWriter();
try {
getMarshaller().marshal(ModelWrapper.wrap(input), writer);
} catch ( JAXBException e ) {
throw new MarshallingException( "Can't marshall input object: "+input, e );
}
return writer.toString();
}
@Override
public <T> T unmarshall(String input, Class<T> type) {
try {
return (T) getUnmarshaller().unmarshal(new StringReader(input));
} catch ( JAXBException e ) {
throw new MarshallingException( "Can't unmarshall input string: "+input, e );
}
}
@Override
public void dispose() {
}
@Override
public MarshallingFormat getFormat() {
return MarshallingFormat.JAXB;
}
protected javax.xml.bind.Marshaller getMarshaller() throws JAXBException {
javax.xml.bind.Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
return marshaller;
}
protected Unmarshaller getUnmarshaller() throws JAXBException {
return jaxbContext.createUnmarshaller();
}
@Override
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public ClassLoader getClassLoader() {
return classLoader;
}
}