/** * Copyright 2013 European Parliament * * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://joinup.ec.europa.eu/software/page/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and limitations under the Licence. */ package org.nsesa.editor.gwt.an.amendments.server.service.gwt; import com.google.common.base.Function; import com.google.common.collect.Collections2; import freemarker.ext.dom.NodeModel; import freemarker.template.Configuration; import freemarker.template.TemplateException; import org.nsesa.editor.gwt.an.common.server.service.gwt.SpringRemoteServiceServlet; import org.nsesa.editor.gwt.core.client.service.gwt.GWTAmendmentService; import org.nsesa.editor.gwt.core.shared.*; import org.nsesa.editor.gwt.core.shared.exception.ResourceNotFoundException; import org.nsesa.editor.gwt.core.shared.exception.StaleResourceException; import org.nsesa.editor.gwt.core.shared.exception.ValidationException; import org.nsesa.server.dto.AmendableWidgetReferenceDTO; import org.nsesa.server.service.api.AmendmentService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.Resource; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.*; /** * Date: 24/06/12 19:57 * * @author <a href="mailto:philip.luppens@gmail.com">Philip Luppens</a> * @version $Id$ */ public class GWTAmendmentServiceImpl extends SpringRemoteServiceServlet implements GWTAmendmentService { private static final Logger LOG = LoggerFactory.getLogger(GWTAmendmentServiceImpl.class); private AmendmentService amendmentService; private Resource documentTemplate; @Override public AmendmentContainerDTO getAmendmentContainer(final ClientContext clientContext, final String id) throws UnsupportedOperationException, ResourceNotFoundException { try { return fromBackend(amendmentService.getAmendmentContainer(id)); } catch (org.nsesa.server.exception.ResourceNotFoundException e) { throw new ResourceNotFoundException(e.getMessage(), e.getCause()); } } @Override public AmendmentContainerDTO getAmendmentContainerRevision(ClientContext clientContext, String revisionID) throws UnsupportedOperationException, ResourceNotFoundException { try { return fromBackend(amendmentService.getAmendmentContainerVersion(revisionID)); } catch (org.nsesa.server.exception.ResourceNotFoundException e) { throw new ResourceNotFoundException(e.getMessage(), e.getCause()); } } @Override public AmendmentContainerDTO[] getAmendmentContainers(final ClientContext clientContext) throws UnsupportedOperationException, ResourceNotFoundException { try { final List<AmendmentContainerDTO> amendmentContainerDTOs = new ArrayList<AmendmentContainerDTO>(); for (final String documentID : clientContext.getDocumentIDs()) { List<org.nsesa.server.dto.AmendmentContainerDTO> backend = null; try { backend = amendmentService.getAmendmentContainersByDocumentAndPerson(documentID, clientContext.getLoggedInPerson().getId()); } catch (org.nsesa.server.exception.ResourceNotFoundException e) { throw new ResourceNotFoundException(e.getMessage(), e.getCause()); } if (backend != null) { for (final org.nsesa.server.dto.AmendmentContainerDTO b : backend) { AmendmentContainerDTO amendmentContainerDTO = fromBackend(b); // transform XML into HTML amendmentContainerDTO.setBody(toHTML(b.getBody().getBytes("UTF-8"))); amendmentContainerDTOs.add(amendmentContainerDTO); } } } return amendmentContainerDTOs.toArray(new AmendmentContainerDTO[amendmentContainerDTOs.size()]); } catch (IOException e) { throw new RuntimeException("Could not retrieve amendment content.", e); } } // TODO use assemblers private AmendmentContainerDTO fromBackend(org.nsesa.server.dto.AmendmentContainerDTO b) { if (b == null) return null; AmendmentContainerDTO amendmentContainerDTO = new AmendmentContainerDTO(); amendmentContainerDTO.setAmendmentContainerStatus(b.getAmendmentContainerStatus()); amendmentContainerDTO.setDocumentID(b.getDocumentID()); final AmendableWidgetReferenceDTO backend = b.getSourceReference(); final AmendableWidgetReference sourceReference = new AmendableWidgetReference(); sourceReference.setNamespaceURI(backend.getNamespaceURI()); sourceReference.setReferenceID(backend.getReferenceID()); sourceReference.setType(backend.getType()); sourceReference.setPath(backend.getPath()); sourceReference.setSibling(backend.isSibling()); sourceReference.setCreation(backend.isCreation()); sourceReference.setOffset(backend.getOffset()); amendmentContainerDTO.setSourceReference(sourceReference); amendmentContainerDTO.setAmendmentAction(org.nsesa.editor.gwt.core.shared.AmendmentAction.valueOf(b.getAmendmentAction().toString())); amendmentContainerDTO.setBody(b.getBody()); amendmentContainerDTO.setId(b.getAmendmentContainerID()); amendmentContainerDTO.setLanguageISO(b.getLanguageISO()); amendmentContainerDTO.setRevisionID(b.getRevisionID()); try { amendmentContainerDTO.setBody(toHTML(amendmentContainerDTO.getBody().getBytes("UTF-8"))); } catch (UnsupportedEncodingException e) { LOG.error("Could not get encoding.", e); } return amendmentContainerDTO; } private String toHTML(byte[] bytes) { try { final InputSource inputSource = new InputSource(new ByteArrayInputStream(bytes)); final NodeModel model = NodeModel.parse(inputSource); final Configuration configuration = new Configuration(); configuration.setDefaultEncoding("UTF-8"); configuration.setDirectoryForTemplateLoading(documentTemplate.getFile().getParentFile()); final StringWriter sw = new StringWriter(); Map<String, Object> root = new HashMap<String, Object>(); root.put("doc", model); configuration.getTemplate(documentTemplate.getFile().getName()).process(root, sw); return sw.toString(); } catch (IOException e) { throw new RuntimeException("Could not read file.", e); } catch (SAXException e) { throw new RuntimeException("Could not parse file.", e); } catch (ParserConfigurationException e) { throw new RuntimeException("Could not parse file.", e); } catch (TemplateException e) { throw new RuntimeException("Could not load template.", e); } } @Override public ArrayList<RevisionDTO> getRevisions(final ClientContext clientContext, final String id) throws UnsupportedOperationException, ResourceNotFoundException { final List<org.nsesa.server.dto.RevisionDTO> amendmentContainerVersions = amendmentService.getAmendmentContainerVersions(id); // manually copy for now final ArrayList<RevisionDTO> revisions = new ArrayList<RevisionDTO>(); for (final org.nsesa.server.dto.RevisionDTO fromBackend : amendmentContainerVersions) { RevisionDTO revisionDTO = new RevisionDTO(); revisionDTO.setRevisionID(fromBackend.getRevisionID()); revisionDTO.setCreationDate(fromBackend.getCreationDate()); revisionDTO.setModificationDate(fromBackend.getModificationDate()); PersonDTO personDTO = new PersonDTO(); personDTO.setId(fromBackend.getPerson().getPersonID()); personDTO.setUsername(fromBackend.getPerson().getUsername()); personDTO.setName(fromBackend.getPerson().getName()); personDTO.setLastName(fromBackend.getPerson().getLastName()); revisionDTO.setPerson(personDTO); revisions.add(revisionDTO); } return revisions; } @Override public AmendmentContainerDTO[] saveAmendmentContainers(final ClientContext clientContext, final ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, StaleResourceException, ValidationException { try { final List<AmendmentContainerDTO> amendmentContainerDTOs = new ArrayList<AmendmentContainerDTO>(); for (final AmendmentContainerDTO data : amendmentContainers) { if (data.getDocumentID() == null) throw new NullPointerException("No documentID set on amendment DTO -- aborting"); if (data.getId() == null) throw new NullPointerException("No ID set on amendment DTO -- aborting"); if (data.getRevisionID() == null) throw new NullPointerException("No revisionID set on amendment DTO -- aborting"); // manually copy for now ... final org.nsesa.server.dto.AmendmentContainerDTO backendDTO = new org.nsesa.server.dto.AmendmentContainerDTO(); backendDTO.setPersonID(clientContext.getLoggedInPerson().getId()); backendDTO.setDocumentID(data.getDocumentID()); backendDTO.setRevisionID(data.getRevisionID()); backendDTO.setAmendmentContainerStatus(data.getAmendmentContainerStatus()); backendDTO.setLanguageISO(data.getLanguageISO()); backendDTO.setAmendmentAction(org.nsesa.server.dto.AmendmentAction.valueOf(data.getAmendmentAction().toString())); backendDTO.setAmendmentContainerID(data.getId()); backendDTO.setBody(data.getBody()); final AmendableWidgetReference dto = data.getSourceReference(); final AmendableWidgetReferenceDTO sourceReference = new AmendableWidgetReferenceDTO(dto.getPath()); sourceReference.setNamespaceURI(dto.getNamespaceURI()); sourceReference.setReferenceID(dto.getReferenceID()); sourceReference.setType(dto.getType()); sourceReference.setPath(dto.getPath()); sourceReference.setSibling(dto.isSibling()); sourceReference.setCreation(dto.isCreation()); sourceReference.setOffset(dto.getOffset()); backendDTO.setSourceReference(sourceReference); final org.nsesa.server.dto.AmendmentContainerDTO saved = amendmentService.save(backendDTO); final AmendmentContainerDTO amendmentContainerDTO = fromBackend(saved); LOG.info("Saved amendment to the dto under document " + amendmentContainerDTO.getDocumentID() + " as revision " + amendmentContainerDTO.getRevisionID()); amendmentContainerDTOs.add(amendmentContainerDTO); } return amendmentContainerDTOs.toArray(new AmendmentContainerDTO[amendmentContainerDTOs.size()]); } catch (org.nsesa.server.exception.StaleResourceException e) { throw new StaleResourceException(e.getMessage(), e.getCause()); } catch (org.nsesa.server.exception.ValidationException e) { throw new ValidationException(e.getMessage(), e.getCause()); } catch (org.nsesa.server.exception.ResourceNotFoundException e) { throw new RuntimeException(e.getMessage(), e.getCause()); } } @Override public Boolean[] canSaveAmendmentContainers(ClientContext clientContext, ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, StaleResourceException { return Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, Boolean>() { @Override public Boolean apply(AmendmentContainerDTO input) { return true; } }).toArray(new Boolean[amendmentContainers.size()]); } @Override public AmendmentContainerDTO[] deleteAmendmentContainers(final ClientContext clientContext, final ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { final Collection<AmendmentContainerDTO> deleted = Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, AmendmentContainerDTO>() { @Override public AmendmentContainerDTO apply(AmendmentContainerDTO input) { amendmentService.delete(input.getId()); input.setAmendmentContainerStatus("deleted"); return input; } }); return deleted.toArray(new AmendmentContainerDTO[deleted.size()]); } @Override public Boolean[] canDeleteAmendmentContainers(ClientContext clientContext, ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { return Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, Boolean>() { @Override public Boolean apply(AmendmentContainerDTO input) { return true; } }).toArray(new Boolean[amendmentContainers.size()]); } @Override public AmendmentContainerDTO[] tableAmendmentContainers(final ClientContext clientContext, final ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { final Collection<AmendmentContainerDTO> tabled = Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, AmendmentContainerDTO>() { @Override public AmendmentContainerDTO apply(AmendmentContainerDTO input) { input.setAmendmentContainerStatus("tabled"); return input; } }); return tabled.toArray(new AmendmentContainerDTO[tabled.size()]); } @Override public Boolean[] canTableAmendmentContainers(ClientContext clientContext, ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { return Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, Boolean>() { @Override public Boolean apply(AmendmentContainerDTO input) { return true; } }).toArray(new Boolean[amendmentContainers.size()]); } @Override public AmendmentContainerDTO[] withdrawAmendmentContainers(final ClientContext clientContext, final ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { final Collection<AmendmentContainerDTO> withdrawn = Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, AmendmentContainerDTO>() { @Override public AmendmentContainerDTO apply(AmendmentContainerDTO input) { input.setAmendmentContainerStatus("withdrawn"); return input; } }); return withdrawn.toArray(new AmendmentContainerDTO[withdrawn.size()]); } @Override public Boolean[] canWithdrawAmendmentContainers(ClientContext clientContext, ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { return Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, Boolean>() { @Override public Boolean apply(AmendmentContainerDTO input) { return true; } }).toArray(new Boolean[amendmentContainers.size()]); } @Override public AmendmentContainerDTO[] registerAmendmentContainers(ClientContext clientContext, ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { final Collection<AmendmentContainerDTO> registered = Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, AmendmentContainerDTO>() { @Override public AmendmentContainerDTO apply(AmendmentContainerDTO input) { input.setAmendmentContainerStatus("registered"); return input; } }); return registered.toArray(new AmendmentContainerDTO[registered.size()]); } @Override public Boolean[] canRegisterAmendmentContainers(ClientContext clientContext, ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { return Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, Boolean>() { @Override public Boolean apply(AmendmentContainerDTO input) { return true; } }).toArray(new Boolean[amendmentContainers.size()]); } @Override public AmendmentContainerDTO[] returnAmendmentContainers(ClientContext clientContext, ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { final Collection<AmendmentContainerDTO> returned = Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, AmendmentContainerDTO>() { @Override public AmendmentContainerDTO apply(AmendmentContainerDTO input) { input.setAmendmentContainerStatus("returned"); return input; } }); return returned.toArray(new AmendmentContainerDTO[returned.size()]); } @Override public Boolean[] canReturnAmendmentContainers(ClientContext clientContext, ArrayList<AmendmentContainerDTO> amendmentContainers) throws UnsupportedOperationException, ResourceNotFoundException, StaleResourceException { return Collections2.transform(amendmentContainers, new Function<AmendmentContainerDTO, Boolean>() { @Override public Boolean apply(AmendmentContainerDTO input) { return true; } }).toArray(new Boolean[amendmentContainers.size()]); } @Override public ArrayList<PersonDTO> getAvailableAuthors(ClientContext clientContext, String query, int limit) { // TODO: this should do an ascii search for potential authors return new ArrayList<PersonDTO>(Arrays.asList(createPerson("1", "mep1", "MEP", "Mep1"), createPerson("2", "mep2", "MEP", "Mep2"))); } private PersonDTO createPerson(String id, String username, String name, String lastName) { final PersonDTO person = new PersonDTO(); person.setLastName(lastName); person.setName(name); person.setUsername(username); person.setId(id); return person; } // SPRING SETTERS ------------------------------------------- public void setDocumentTemplate(Resource documentTemplate) { this.documentTemplate = documentTemplate; } public void setAmendmentService(AmendmentService amendmentService) { this.amendmentService = amendmentService; } }