/******************************************************************************* * Copyright (c) 2015 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.boot.properties.editor.reconciling; import static org.springframework.ide.eclipse.boot.properties.editor.StsConfigMetadataRepositoryJsonLoader.ADDITIONAL_SPRING_CONFIGURATION_METADATA_JSON; import java.io.ByteArrayInputStream; import java.util.ArrayList; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.internal.ui.JavaPluginImages; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.IContextInformation; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.springframework.ide.eclipse.boot.core.BootActivator; import org.springframework.ide.eclipse.boot.properties.editor.quickfix.MetaDataManipulator; import org.springframework.ide.eclipse.boot.util.JavaProjectUtil; import org.springframework.ide.eclipse.editor.support.util.UserInteractions; import org.springsource.ide.eclipse.commons.frameworks.core.ExceptionUtil; @SuppressWarnings("restriction") public class CreateAdditionalMetadataQuickfix implements ICompletionProposal { private static final IPath METADATA_PATH = new Path(ADDITIONAL_SPRING_CONFIGURATION_METADATA_JSON); private IJavaProject project; private String missingPropertyKey; private UserInteractions ui; public CreateAdditionalMetadataQuickfix(IJavaProject project, String missingProperty, UserInteractions ui) { Assert.isNotNull(ui); this.project = project; this.missingPropertyKey = missingProperty; this.ui = ui; } @Override public void apply(IDocument document) { try { IFile file = getMetadataFile(project); if (file!=null) { addDefaultMetadataTo(file); } } catch (Exception e) { BootActivator.log(e); } } private IFile getMetadataFile(IJavaProject project) { try { boolean includeDerived = false; IContainer[] srcRoots = JavaProjectUtil.getSourceFolders(project, includeDerived); IFile file = findExistingMetadataFile(srcRoots); if (file==null) { IContainer srcRoot = chooseSourceFolder(srcRoots); if (srcRoot!=null) { file = createMetadataFile(srcRoot); } } return file; } catch (CoreException e) { BootActivator.log(e); } return null; } private IFile createMetadataFile(IContainer srcRoot) throws CoreException { IFile toCreate = srcRoot.getFile(METADATA_PATH); createFolder(toCreate.getParent()); toCreate.create(new ByteArrayInputStream("".getBytes()), true, new NullProgressMonitor()); return toCreate; } private void createFolder(IContainer container) throws CoreException { if (!container.exists()) { if (container instanceof IFolder) { IFolder folder = (IFolder) container; folder.create(true, true, new NullProgressMonitor()); } else { throw ExceptionUtil.coreException("Can't create folder '"+container+"': not a IFolder instance"); } } } private IContainer chooseSourceFolder(IContainer[] srcRoots) { if (srcRoots.length==1) { return srcRoots[0]; } else if (srcRoots.length>1) { return ui.chooseOneSourceFolder("Create Metadata File?", "No existing metadata file found. Choose a source folder to create one.", srcRoots, getPreferredSourceFolder(srcRoots) ); } return null; } private IContainer getPreferredSourceFolder(IContainer[] srcRoots) { for (IContainer f : srcRoots) { if ("resources".equals(f.getFullPath().lastSegment())) { return f; } } return null; } private void addDefaultMetadataTo(IFile file) throws Exception { MetaDataManipulator metadata = new MetaDataManipulator(file); if (!metadata.isReliable()) { ui.error("Failed to add metadata!", "'"+file.getFullPath()+"' does not appear to contain valid JSON!\n"); } else { metadata.addDefaultInfo(missingPropertyKey); metadata.save(); } } private IFile findExistingMetadataFile(IContainer[] srcRoots) { for (IContainer srcFolder : srcRoots) { IFile file = srcFolder.getFile(METADATA_PATH); if (file.exists()) { return file; } } return null; } @Override public Point getSelection(IDocument document) { return null; } @Override public String getAdditionalProposalInfo() { return "Add property '" + missingPropertyKey + "' to the 'additional-spring-configuration-metadata.json' file" + " in project '"+getProjectName()+"'"; } private String getProjectName() { return project.getProject().getName(); } @Override public String getDisplayString() { return "Create metadata for '"+missingPropertyKey+"'."; } @Override public Image getImage() { return JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_ADD); } @Override public IContextInformation getContextInformation() { return null; } }