package eu.dnetlib.enabling.tools.blackboard; import java.io.PrintWriter; import java.io.StringWriter; import javax.xml.bind.JAXBException; import javax.xml.transform.dom.DOMSource; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.springframework.beans.factory.annotation.Required; import org.w3c.dom.Element; import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException; import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService; import eu.dnetlib.enabling.locators.UniqueServiceLocator; import eu.dnetlib.enabling.tools.OpaqueResource; import eu.dnetlib.miscutils.jaxb.JaxbFactory; /** * Blackboard handler implementation. * * @author marko * */ public class BlackboardHandlerImpl implements BlackboardServerHandler { /** * blackboard message factory. */ private JaxbFactory messageFactory; /** * service locator. */ private UniqueServiceLocator serviceLocator; /** * {@inheritDoc} * * @see eu.dnetlib.enabling.tools.blackboard.BlackboardHandler#getJob(eu.dnetlib.enabling.tools.OpaqueResource) */ @Override public BlackboardJob getJob(final OpaqueResource profile) { final XPath xpa = XPathFactory.newInstance().newXPath(); try { final Element source = (Element) xpa.evaluate("/RESOURCE_PROFILE/BODY/BLACKBOARD/MESSAGE[@id = /RESOURCE_PROFILE/BODY/BLACKBOARD/LAST_REQUEST]", profile.asDom(), XPathConstants.NODE); if (source == null) { throw new IllegalStateException("cannot find last blackboard message in the service profile"); } return new BlackboardJobImpl(profile.getResourceId(), messageFactory.parse(new DOMSource(source))); } catch (final JAXBException e) { throw new IllegalStateException("cannot parse blackboard message", e); } catch (final XPathExpressionException e) { throw new IllegalStateException("cannot find last blackboard message in the service profile", e); } } /** * {@inheritDoc} * * @see eu.dnetlib.enabling.tools.blackboard.BlackboardHandler#done(eu.dnetlib.enabling.tools.blackboard.BlackboardJob) */ @Override public void done(final BlackboardJob job) { job.setActionStatus(ActionStatus.DONE); replyJob(job); } /** * {@inheritDoc} * * @see eu.dnetlib.enabling.tools.blackboard.BlackboardHandler#failed(eu.dnetlib.enabling.tools.blackboard.BlackboardJob, * java.lang.Exception) */ @Override public void failed(final BlackboardJob job, final Throwable exception) { job.setActionStatus(ActionStatus.FAILED); final StringWriter stackTrace = new StringWriter(); exception.printStackTrace(new PrintWriter(stackTrace)); job.getParameters().put("error", exception.toString()); job.getParameters().put("errorDetails", stackTrace.toString()); replyJob(job); } /** * {@inheritDoc} * * @see eu.dnetlib.enabling.tools.blackboard.BlackboardHandler#ongoing(eu.dnetlib.enabling.tools.blackboard.BlackboardJob) */ @Override public void ongoing(final BlackboardJob job) { job.setActionStatus(ActionStatus.ONGOING); replyJob(job); } /** * Internal helper method which replies a blackboard job. * * @param job * blackboard job */ protected void replyJob(final BlackboardJob job) { try { serviceLocator.getService(ISRegistryService.class).replyBlackBoardMessage(job.getServiceId(), messageFactory.serialize(job.getMessage())); } catch (final ISRegistryException e) { throw new IllegalStateException("cannot reply the blackboard message", e); } catch (final JAXBException e) { throw new IllegalArgumentException("cannot serialize blackboard message", e); } } public JaxbFactory getMessageFactory() { return messageFactory; } public void setMessageFactory(final JaxbFactory messageFactory) { this.messageFactory = messageFactory; } public UniqueServiceLocator getServiceLocator() { return serviceLocator; } @Required public void setServiceLocator(final UniqueServiceLocator serviceLocator) { this.serviceLocator = serviceLocator; } }