Java tutorial
/** * Copyright (C) 2011 Red Hat, Inc. (jdcasey@commonjava.org) * * 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.commonjava.aprox.depgraph.rest; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Collections; import java.util.Map; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Writer; import org.commonjava.aprox.AproxWorkflowException; import org.commonjava.aprox.depgraph.conf.AproxDepgraphConfig; import org.commonjava.aprox.depgraph.dto.WebBomDTO; import org.commonjava.aprox.depgraph.dto.WebOperationConfigDTO; import org.commonjava.aprox.depgraph.util.ConfigDTOHelper; import org.commonjava.aprox.depgraph.util.PresetParameterParser; import org.commonjava.aprox.depgraph.util.RequestAdvisor; import org.commonjava.aprox.util.ApplicationStatus; import org.commonjava.maven.atlas.graph.RelationshipGraph; import org.commonjava.maven.atlas.graph.RelationshipGraphException; import org.commonjava.maven.atlas.graph.RelationshipGraphFactory; import org.commonjava.maven.atlas.graph.ViewParams; import org.commonjava.maven.atlas.graph.filter.ProjectRelationshipFilter; import org.commonjava.maven.atlas.graph.mutate.GraphMutator; import org.commonjava.maven.atlas.graph.mutate.ManagedDependencyMutator; import org.commonjava.maven.atlas.ident.DependencyScope; import org.commonjava.maven.atlas.ident.ref.ProjectVersionRef; import org.commonjava.maven.cartographer.data.CartoDataException; import org.commonjava.maven.cartographer.data.CartoGraphUtils; import org.commonjava.maven.cartographer.dto.GraphCalculation.Type; import org.commonjava.maven.cartographer.dto.GraphComposition; import org.commonjava.maven.cartographer.dto.GraphDescription; import org.commonjava.maven.cartographer.ops.GraphRenderingOps; import org.commonjava.maven.cartographer.ops.ResolveOps; import org.commonjava.maven.cartographer.preset.CommonPresetParameters; import org.commonjava.maven.cartographer.preset.PresetSelector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @ApplicationScoped // FIXME: DTO Validations!! public class RenderingController { @Inject private GraphRenderingOps ops; @Inject private RequestAdvisor requestAdvisor; @Inject private ConfigDTOHelper configHelper; @Inject private PresetSelector presets; @Inject private AproxDepgraphConfig config; @Inject private PresetParameterParser presetParamParser; @Inject private ObjectMapper serializer; @Inject private ResolveOps resolveOps; @Inject private RelationshipGraphFactory graphFactory; private final Logger logger = LoggerFactory.getLogger(getClass()); public File tree(final InputStream configStream) throws AproxWorkflowException { final WebOperationConfigDTO dto = configHelper.readWebOperationDTO(configStream); return tree(dto); } public File tree(final String json) throws AproxWorkflowException { final WebOperationConfigDTO dto = configHelper.readWebOperationDTO(json); return tree(dto); } private File tree(final WebOperationConfigDTO dto) throws AproxWorkflowException { final File workBasedir = config.getWorkBasedir(); String dtoJson; try { dtoJson = serializer.writeValueAsString(dto); } catch (final JsonProcessingException e) { throw new AproxWorkflowException("Failed to serialize to JSON: %s", e, e.getMessage()); } final File out = new File(workBasedir, DigestUtils.md5Hex(dtoJson)); workBasedir.mkdirs(); final GraphComposition comp = resolve(dto); FileWriter w = null; try { w = new FileWriter(out); ops.depTree(dto.getWorkspaceId(), comp, false, new PrintWriter(w)); } catch (final CartoDataException e) { throw new AproxWorkflowException("Failed to generate dependency tree. Reason: {}", e, e.getMessage()); } catch (final IOException e) { throw new AproxWorkflowException("Failed to open work file for caching output: {}. Reason: {}", e, out, e.getMessage()); } finally { IOUtils.closeQuietly(w); } return out; } @Deprecated public File tree(final String groupId, final String artifactId, final String version, final String workspaceId, final DependencyScope scope, final Map<String, String[]> params) throws AproxWorkflowException { final ProjectVersionRef ref = new ProjectVersionRef(groupId, artifactId, version); final Map<String, Object> parsed = presetParamParser.parse(params); if (!parsed.containsKey(CommonPresetParameters.SCOPE)) { parsed.put(CommonPresetParameters.SCOPE, scope == null ? DependencyScope.runtime : scope); } final ProjectRelationshipFilter filter = requestAdvisor.createRelationshipFilter(params, parsed); final WebOperationConfigDTO dto = new WebOperationConfigDTO(); dto.setWorkspaceId(workspaceId); final GraphDescription desc = new GraphDescription(filter, ref); dto.setGraphComposition(new GraphComposition(Type.ADD, Collections.singletonList(desc))); return tree(dto); } @Deprecated public String bomFor(final String groupId, final String artifactId, final String version, final String workspaceId, final Map<String, String[]> params, final InputStream configStream) throws AproxWorkflowException { final WebBomDTO config = configHelper.readBomDTO(configStream); return bomFor(groupId, artifactId, version, workspaceId, params, config); } @Deprecated public String bomFor(final String groupId, final String artifactId, final String version, final String workspaceId, final Map<String, String[]> params, final String configJson) throws AproxWorkflowException { final WebBomDTO config = configHelper.readBomDTO(configJson); return bomFor(groupId, artifactId, version, workspaceId, params, config); } @Deprecated public String bomFor(final String groupId, final String artifactId, final String version, final String workspaceId, final Map<String, String[]> params, final WebBomDTO config) throws AproxWorkflowException { final ProjectVersionRef pvr = new ProjectVersionRef(groupId, artifactId, version); config.setOutput(pvr); return bomFor(config); } public String bomFor(final InputStream configStream) throws AproxWorkflowException { final WebBomDTO config = configHelper.readBomDTO(configStream); return bomFor(config); } public String bomFor(final String configJson) throws AproxWorkflowException { final WebBomDTO config = configHelper.readBomDTO(configJson); return bomFor(config); } public String bomFor(final WebBomDTO config) throws AproxWorkflowException { try { final Model model = ops.generateBOM(config); final StringWriter writer = new StringWriter(); new MavenXpp3Writer().write(writer, model); return writer.toString(); } catch (final IOException e) { throw new AproxWorkflowException(ApplicationStatus.BAD_REQUEST.code(), "Failed to render BOM: {}", e, e.getMessage()); } catch (final CartoDataException e) { throw new AproxWorkflowException(ApplicationStatus.SERVER_ERROR.code(), "Failed to generate BOM for: {} using config: {}. Reason: {}", e, config, e.getMessage()); } } public String dotfile(final String groupId, final String artifactId, final String version, final String workspaceId, final Map<String, String[]> params) throws AproxWorkflowException { // final DiscoveryConfig discovery = createDiscoveryConfig( request, null, sourceFactory ); final ProjectRelationshipFilter filter = requestAdvisor.createRelationshipFilter(params, presetParamParser.parse(params)); final GraphMutator mutator = new ManagedDependencyMutator(); RelationshipGraph graph = null; try { final ProjectVersionRef ref = new ProjectVersionRef(groupId, artifactId, version); graph = graphFactory.open(new ViewParams(workspaceId, filter, mutator, ref), true); final String dotfile = ops.dotfile(ref, graph); if (dotfile != null) { return dotfile; } else { throw new AproxWorkflowException(ApplicationStatus.NOT_FOUND.code(), "Cannot find graph: {}:{}:{} in workspace: {}", groupId, artifactId, version, workspaceId); } } catch (final CartoDataException e) { throw new AproxWorkflowException(ApplicationStatus.SERVER_ERROR.code(), "Failed to render DOT file for: {}:{}:{} in workspace: {}. Reason: {}", e, groupId, artifactId, version, workspaceId, e.getMessage(), e); } catch (final RelationshipGraphException e) { throw new AproxWorkflowException(ApplicationStatus.SERVER_ERROR.code(), "Failed to render DOT file for: {}:{}:{} in workspace: {}. Reason: {}", e, groupId, artifactId, version, workspaceId, e.getMessage(), e); } finally { CartoGraphUtils.closeGraphQuietly(graph); } } private GraphComposition resolve(final WebOperationConfigDTO dto) throws AproxWorkflowException { if (dto == null) { logger.warn("Repository archive configuration is missing."); throw new AproxWorkflowException(ApplicationStatus.BAD_REQUEST.code(), "JSON configuration not supplied"); } dto.resolveFilters(presets, config.getDefaultWebFilterPreset()); if (!dto.isValid()) { logger.warn("Repository archive configuration is invalid: {}", dto); throw new AproxWorkflowException(ApplicationStatus.BAD_REQUEST.code(), "Invalid configuration: {}", dto); } GraphComposition result; try { result = resolveOps.resolve(dto); } catch (final CartoDataException e) { logger.error( String.format("Failed to resolve repository contents for: %s. Reason: %s", dto, e.getMessage()), e); throw new AproxWorkflowException("Failed to resolve repository contents for: {}. Reason: {}", e, dto, e.getMessage()); } return result; } }