/* * Copyright 2013 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * 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.artificer.ui.server.services; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.Iterator; import java.util.List; import javax.enterprise.context.ApplicationScoped; import org.apache.commons.io.IOUtils; import org.artificer.client.ArtificerClientException; import org.artificer.common.ArtifactType; import org.artificer.common.ArtificerModelUtils; import org.artificer.common.error.ArtificerServerException; import org.artificer.ui.client.shared.beans.ArtifactBean; import org.artificer.ui.client.shared.beans.ArtifactCommentBean; import org.artificer.ui.client.shared.beans.ArtifactRelationshipBean; import org.artificer.ui.client.shared.beans.ArtifactRelationshipsBean; import org.artificer.ui.client.shared.beans.ArtifactRelationshipsIndexBean; import org.artificer.ui.client.shared.exceptions.ArtificerUiException; import org.artificer.ui.client.shared.services.IArtifactService; import org.artificer.ui.server.api.ArtificerApiClientAccessor; import org.artificer.ui.server.i18n.Messages; import org.artificer.ui.server.services.util.RelationshipResolver; import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.BaseArtifactType; import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.Comment; import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.DocumentArtifactType; import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.Property; import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.Relationship; import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.Target; /** * Concrete implementation of the artifact service. * * @author eric.wittmann@redhat.com */ @ApplicationScoped public class ArtifactService implements IArtifactService { // Limit content grabs to 2mb private static final Long TWO_MEG = 2l * 1024l * 1024l; /** * Constructor. */ public ArtifactService() { } /** * @see org.artificer.ui.client.shared.services.IArtifactService#get(java.lang.String) */ @Override public ArtifactBean get(String uuid) throws ArtificerUiException { try { BaseArtifactType artifact = ArtificerApiClientAccessor.getClient().getArtifactMetaData(uuid); ArtifactType artifactType = ArtifactType.valueOf(artifact); ArtifactBean bean = new ArtifactBean(); bean.setModel(artifactType.getArtifactType().getModel()); bean.setType(artifactType.getType()); bean.setRawType(artifactType.getArtifactType().getType()); bean.setUuid(artifact.getUuid()); bean.setName(artifact.getName()); bean.setDescription(artifact.getDescription()); bean.setVersion(artifact.getVersion()); bean.setCreatedBy(artifact.getCreatedBy()); bean.setCreatedOn(artifact.getCreatedTimestamp().toGregorianCalendar().getTime()); bean.setUpdatedOn(artifact.getLastModifiedTimestamp().toGregorianCalendar().getTime()); bean.setUpdatedBy(artifact.getLastModifiedBy()); bean.setDerived(artifactType.isDerived()); bean.setRepositoryLink(getRepositoryLink(artifact, artifactType)); bean.setRepositoryMediaLink(getRepositoryMediaLink(artifact, artifactType)); if (ArtificerModelUtils.isDocumentArtifact(artifact)) { DocumentArtifactType doc = (DocumentArtifactType) artifact; bean.setContentSize(doc.getContentSize()); bean.setContentType(doc.getContentType()); if (ArtificerModelUtils.isTextDocumentArtifact(doc)) { bean.setTextDocument(true); } } // Properties for (Property property : artifact.getProperty()) { bean.setProperty(property.getPropertyName(), property.getPropertyValue()); } // Classifications bean.getClassifiedBy().addAll(artifact.getClassifiedBy()); // Num Relationships int numRelationships = artifact.getRelationship() == null ? 0 : artifact.getRelationship().size(); bean.setNumRelationships(numRelationships); // Comments for (Comment comment : artifact.getComment()) { bean.getComments().add(toCommentBean(comment)); } return bean; } catch (ArtificerClientException e) { throw new ArtificerUiException(e.getMessage()); } catch (ArtificerServerException e) { throw new ArtificerUiException(e.getMessage()); } } private ArtifactCommentBean toCommentBean(Comment comment) { ArtifactCommentBean commentBean = new ArtifactCommentBean(); commentBean.setCreatedBy(comment.getCreatedBy()); commentBean.setCreatedOn(comment.getCreatedTimestamp().toGregorianCalendar().getTime()); commentBean.setText(comment.getText()); return commentBean; } /** * @see org.artificer.ui.client.shared.services.IArtifactService#getDocumentContent(java.lang.String, java.lang.String) */ @Override public String getDocumentContent(String uuid, String artifactType) throws ArtificerUiException { try { ArtifactType at = ArtifactType.valueOf(artifactType); BaseArtifactType artifact = ArtificerApiClientAccessor.getClient().getArtifactMetaData(at, uuid); String response = Messages.i18n.format("ArtifactService.DownloadContent"); if (ArtificerModelUtils.isDocumentArtifact(artifact)) { DocumentArtifactType doc = (DocumentArtifactType) artifact; if (ArtificerModelUtils.isTextDocumentArtifact(doc) && doc.getContentSize() <= TWO_MEG) { InputStream content = null; try { content = ArtificerApiClientAccessor.getClient().getArtifactContent(at, uuid); ByteArrayOutputStream baos = new ByteArrayOutputStream(); IOUtils.copy(content, baos); // TODO: obey the document's encoding here (if we can find it) but default to UTF-8 response = baos.toString("UTF-8"); } finally { IOUtils.closeQuietly(content); } } } return response; } catch (Exception e) { throw new ArtificerUiException(e.getMessage()); } } /** * @see org.artificer.ui.client.shared.services.IArtifactService#getRelationships(java.lang.String, java.lang.String) */ @Override public ArtifactRelationshipsIndexBean getRelationships(String uuid, String artifactType) throws ArtificerUiException { ArtifactRelationshipsIndexBean rval = new ArtifactRelationshipsIndexBean(); try { ArtifactType at = ArtifactType.valueOf(artifactType); BaseArtifactType artifact = ArtificerApiClientAccessor.getClient().getArtifactMetaData(at, uuid); RelationshipResolver relResolver = new RelationshipResolver(ArtificerApiClientAccessor.getClient(), rval); relResolver.resolveAll(artifact); } catch (ArtificerClientException e) { throw new ArtificerUiException(e.getMessage()); } catch (ArtificerServerException e) { throw new ArtificerUiException(e.getMessage()); } return rval; } /** * @see org.artificer.ui.client.shared.services.IArtifactService#update(org.artificer.ui.client.shared.beans.ArtifactBean) */ @Override public void update(ArtifactBean bean) throws ArtificerUiException { try { ArtifactType artifactType = ArtifactType.valueOf(bean.getModel(), bean.getRawType(), null); // Grab the latest from the server BaseArtifactType artifact = ArtificerApiClientAccessor.getClient().getArtifactMetaData(artifactType, bean.getUuid()); // Update it with new data from the bean artifact.setName(bean.getName()); artifact.setDescription(bean.getDescription()); artifact.setVersion(bean.getVersion()); artifact.getProperty().clear(); for (String propName : bean.getPropertyNames()) { ArtificerModelUtils.setCustomProperty(artifact, propName, bean.getProperty(propName)); } artifact.getClassifiedBy().clear(); if (bean.getClassifiedBy() != null && !bean.getClassifiedBy().isEmpty()) { for (String classifier : bean.getClassifiedBy()) { artifact.getClassifiedBy().add(classifier); } } // Push the changes back to the server ArtificerApiClientAccessor.getClient().updateArtifactMetaData(artifact); } catch (ArtificerClientException e) { throw new ArtificerUiException(e.getMessage()); } catch (ArtificerServerException e) { throw new ArtificerUiException(e.getMessage()); } } @Override public ArtifactCommentBean addComment(String uuid, String artifactType, String text) throws ArtificerUiException { try { ArtifactType at = ArtifactType.valueOf(artifactType); BaseArtifactType artifact = ArtificerApiClientAccessor.getClient().addComment(uuid, at, text); List<Comment> comments = artifact.getComment(); // latest should be last return(toCommentBean(comments.get(comments.size() - 1))); } catch (ArtificerClientException e) { throw new ArtificerUiException(e.getMessage()); } catch (ArtificerServerException e) { throw new ArtificerUiException(e.getMessage()); } } /** * @see org.artificer.ui.client.shared.services.IArtifactService#delete(org.artificer.ui.client.shared.beans.ArtifactBean) */ @Override public void delete(ArtifactBean bean) throws ArtificerUiException { try { ArtifactType artifactType = ArtifactType.valueOf(bean.getModel(), bean.getRawType(), null); ArtificerApiClientAccessor.getClient().deleteArtifact(bean.getUuid(), artifactType); } catch (ArtificerClientException e) { throw new ArtificerUiException(e.getMessage()); } catch (ArtificerServerException e) { throw new ArtificerUiException(e.getMessage()); } } @Override public void addRelationships(String sourceUuid, ArtifactRelationshipsBean relationships) throws ArtificerUiException { try { BaseArtifactType artifact = ArtificerApiClientAccessor.getClient().getArtifactMetaData(sourceUuid); for (ArtifactRelationshipBean relationshipBean : relationships.getRelationships()) { Relationship relationship = new Relationship(); relationship.setRelationshipType(relationshipBean.getRelationshipType()); Target target = new Target(); target.setValue(relationshipBean.getTargetUuid()); relationship.getRelationshipTarget().add(target); artifact.getRelationship().add(relationship); } ArtificerApiClientAccessor.getClient().updateArtifactMetaData(artifact); } catch (ArtificerClientException e) { throw new ArtificerUiException(e.getMessage()); } catch (ArtificerServerException e) { throw new ArtificerUiException(e.getMessage()); } } @Override public void editRelationship(String relationshipType, String newRelationshipType, String sourceUuid, String targetUuid) throws ArtificerUiException { try { BaseArtifactType artifact = ArtificerApiClientAccessor.getClient().getArtifactMetaData(sourceUuid); doDeleteRelationship(artifact, relationshipType, targetUuid); Relationship relationship = new Relationship(); relationship.setRelationshipType(newRelationshipType); Target target = new Target(); target.setValue(targetUuid); relationship.getRelationshipTarget().add(target); artifact.getRelationship().add(relationship); ArtificerApiClientAccessor.getClient().updateArtifactMetaData(artifact); } catch (ArtificerClientException e) { throw new ArtificerUiException(e.getMessage()); } catch (ArtificerServerException e) { throw new ArtificerUiException(e.getMessage()); } } @Override public void deleteRelationship(String relationshipType, String sourceUuid, String targetUuid) throws ArtificerUiException { try { BaseArtifactType artifact = ArtificerApiClientAccessor.getClient().getArtifactMetaData(sourceUuid); doDeleteRelationship(artifact, relationshipType, targetUuid); ArtificerApiClientAccessor.getClient().updateArtifactMetaData(artifact); } catch (ArtificerClientException e) { throw new ArtificerUiException(e.getMessage()); } catch (ArtificerServerException e) { throw new ArtificerUiException(e.getMessage()); } } private void doDeleteRelationship(BaseArtifactType artifact, String relationshipType, String targetUuid) { for (Relationship relationship : artifact.getRelationship()) { if (relationship.getRelationshipType().equals(relationshipType)) { Iterator<Target> itr = relationship.getRelationshipTarget().iterator(); while (itr.hasNext()) { Target target = itr.next(); if (target.getValue().equals(targetUuid)) { itr.remove(); break; } } } } } /** * Creates a link to the remote repository for the given artifact. * @param artifact * @param artifactType */ private String getRepositoryLink(BaseArtifactType artifact, ArtifactType artifactType) { StringBuilder builder = new StringBuilder(); String endpoint = ArtificerApiClientAccessor.getClient().getEndpoint(); builder.append(endpoint); if (!endpoint.endsWith("/")) { builder.append("/"); } builder.append("s-ramp/"); builder.append(artifactType.getModel()); builder.append("/"); builder.append(artifactType.getType()); builder.append("/"); builder.append(artifact.getUuid()); return builder.toString(); } /** * Creates a media link to the remote repository for the given artifact. * @param artifact * @param artifactType */ private String getRepositoryMediaLink(BaseArtifactType artifact, ArtifactType artifactType) { return getRepositoryLink(artifact, artifactType) + "/media"; } }