All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.maven.configurations.M2Configuration Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.netbeans.modules.maven.configurations;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.modules.maven.api.MavenConfiguration;
import static org.netbeans.modules.maven.configurations.Bundle.*;
import org.netbeans.modules.maven.execute.model.ActionToGoalMapping;
import org.netbeans.modules.maven.execute.model.NetbeansActionMapping;
import org.netbeans.modules.maven.execute.model.NetbeansActionProfile;
import org.netbeans.modules.maven.execute.model.NetbeansActionReader;
import org.netbeans.modules.maven.execute.model.io.xpp3.NetbeansBuildActionXpp3Writer;
import org.netbeans.modules.maven.spi.actions.AbstractMavenActionsProvider;
import org.netbeans.modules.maven.spi.actions.MavenActionsProvider;
import org.openide.filesystems.FileChangeAdapter;
import org.openide.filesystems.FileChangeListener;
import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileRenameEvent;
import org.openide.filesystems.FileUtil;
import org.openide.util.NbBundle.Messages;

/**
 * Represents a configuration, Properties defined by {@link MavenConfiguration} plus list of action descriptions
 * for that configuration. This class is used to represent:
 * 
    *
  • default configurations, provided by Maven project. *
  • profile-based configurations *
  • user-customized configurations, that loads action configs from the project directory. *
* * @author mkleint */ public class M2Configuration extends AbstractMavenActionsProvider implements MavenConfiguration, Comparable { private static final Logger LOG = Logger.getLogger(M2Configuration.class.getName()); public static final String DEFAULT = "%%DEFAULT%%"; //NOI18N public static final String FILENAME = "nbactions.xml"; //NOI18N public static final String FILENAME_PREFIX = "nbactions-"; //NOI18N public static final String FILENAME_SUFFIX = ".xml"; //NOI18N public static M2Configuration createDefault(FileObject projectDirectory) { return new M2Configuration(DEFAULT, projectDirectory); } /** * True, if the M2Configuration comes from a customized project storage. */ private boolean customized; private @NonNull final String id; private List profiles; private final Map properties = new HashMap(); private final FileObject projectDirectory; private final AtomicBoolean resetCache = new AtomicBoolean(false); private FileChangeListener listener = null; private String displayName; public M2Configuration(String id, FileObject projectDirectory) { assert id != null; this.id = id; this.projectDirectory = projectDirectory; profiles = Collections.emptyList(); } @Override @Messages("TXT_DefaultConfig=") public String getDisplayName() { if (DEFAULT.equals(id)) { return TXT_DefaultConfig(); } return displayName != null ? displayName : id; } void setDisplayName(String displayName) { this.displayName = displayName; } public @NonNull String getId() { return id; } public void setActivatedProfiles(List profs) { profiles = profs; } @Override public List getActivatedProfiles() { return profiles; } @Override public Map getProperties() { return properties; } public void setProperties(Map props) { if (props == null) { props = Collections.emptyMap(); } properties.clear(); properties.putAll(props); } public static String getFileNameExt(String id) { if (DEFAULT.equals(id)) { return FILENAME; } return FILENAME_PREFIX + id + FILENAME_SUFFIX; } public @Override boolean equals(Object obj) { return obj instanceof M2Configuration && id.equals(((M2Configuration) obj).id); } public @Override int hashCode() { return id.hashCode(); } @Override public String toString() { return id; } public @Override int compareTo(M2Configuration o) { return id.compareTo(o.id); } public @Override InputStream getActionDefinitionStream() { return getActionDefinitionStream(id); } public boolean isCustomized() { return customized; } final InputStream getActionDefinitionStream(String forId) { checkListener(); FileObject fo = projectDirectory.getFileObject(getFileNameExt(forId)); customized = fo != null; resetCache.set(false); if (fo != null) { try { return fo.getInputStream(); } catch (FileNotFoundException ex) { LOG.log(Level.WARNING, "Cannot read " + fo, ex); // NOI18N } } return null; } private synchronized void checkListener() { final String fid = getFileNameExt(id); if (listener == null) { listener = new FileChangeAdapter() { @Override public void fileRenamed(FileRenameEvent fe) { if (fid.equals(fe.getName() + "." + fe.getExt())) { resetCache(); } } @Override public void fileDeleted(FileEvent fe) { if (fid.equals(fe.getFile().getNameExt())) { resetCache(); } } @Override public void fileChanged(FileEvent fe) { if (fid.equals(fe.getFile().getNameExt())) { resetCache(); } } @Override public void fileDataCreated(FileEvent fe) { if (fid.equals(fe.getFile().getNameExt())) { resetCache(); } } }; projectDirectory.addFileChangeListener(FileUtil.weakFileChangeListener(listener, projectDirectory)); } } private void resetCache() { resetCache.compareAndSet(false, true); } /** * get custom action maven mapping configuration * No replacements happen. * The instances returned is always a new copy, can be modified or reused. * Same method in NbGlobalActionGolaProvider */ public NetbeansActionMapping[] getCustomMappings() { NetbeansActionMapping[] fallbackActions = new NetbeansActionMapping[0]; try { List toRet = new ArrayList(); // just a converter for the To-Object reader.. Reader read = performDynamicSubstitutions(Collections.emptyMap(), getRawMappingsAsString()); // basically doing a copy here.. ActionToGoalMapping mapping = reader.read(read); for (NetbeansActionMapping mapp : mapping.getActions()) { if (mapp.getActionName().startsWith("CUSTOM-")) { //NOI18N toRet.add(mapp); } } return toRet.toArray(new NetbeansActionMapping[0]); } catch (XmlPullParserException ex) { LOG.log(Level.WARNING, null, ex); } catch (IOException ex) { LOG.log(Level.WARNING, null, ex); } return fallbackActions; } @Override protected boolean reloadStream() { return resetCache.get(); } @Override public ActionToGoalMapping getRawMappings() { if (originalMappings == null || reloadStream()) { Reader rdr = null; InputStream in = getActionDefinitionStream(); try { if (in == null) { in = getActionDefinitionStream(DEFAULT); if (in != null) { rdr = new InputStreamReader(in); ActionToGoalMapping def = reader.read(rdr); for (NetbeansActionProfile p : def.getProfiles()) { if (id.equals(p.getId()) && p.getActions() != null) { Map posMap = new HashMap<>(); for (int i = 0; i < def.getActions().size(); i++) { posMap.put(def.getActions().get(i).getActionName(), i); } // merge in or override global actions: for (NetbeansActionMapping am : p.getActions()) { String n = am.getActionName(); Integer i = posMap.get(n); if (null == i) { def.getActions().add(am); } else { def.getActions().set(i, am); } } break; } } originalMappings = def; } else { originalMappings = new ActionToGoalMapping(); } } else { rdr = new InputStreamReader(in); originalMappings = reader.read(rdr); } } catch (IOException ex) { LOG.log(Level.INFO, "Loading raw mappings", ex); } catch (XmlPullParserException ex) { LOG.log(Level.INFO, "Loading raw mappings", ex); } finally { if (rdr != null) { try { rdr.close(); } catch (IOException ex) { } } } if (originalMappings == null) { originalMappings = new ActionToGoalMapping(); } } return originalMappings; } public NetbeansActionMapping getProfileMappingForAction( String action, Project project, Map replaceMap, boolean[] fallback ) { NetbeansActionReader parsed = new NetbeansActionReader() { @Override protected String getRawMappingsAsString() { NetbeansBuildActionXpp3Writer writer = new NetbeansBuildActionXpp3Writer(); StringWriter str = new StringWriter(); InputStreamReader rdr = null; try { // relay the action load to the possibly customized getRawMappings ActionToGoalMapping map = getRawMappings(); writer.write(str, map); } catch (IOException ex) { LOG.log(Level.WARNING, "Loading raw mappings", ex); } finally { if(rdr != null) { try { rdr.close(); } catch (IOException ex) { } } } return str.toString(); } @Override protected Reader performDynamicSubstitutions(Map replaceMap, String in) throws IOException { return M2Configuration.this.performDynamicSubstitutions(replaceMap, in); } }; NetbeansActionMapping ret = parsed.getMappingForAction(reader, LOG, action, null, project, id, replaceMap); if (ret == null) { boolean[] hasProfiles = { false }; ret = parsed.getMappingForAction(reader, LOG, action, hasProfiles, project, null, replaceMap); if (fallback != null && ret != null && hasProfiles[0]) { fallback[0] = true; } } return ret; } public NetbeansActionMapping findMappingFor( Map replaceMap, Project project, String actionName, boolean[] fallback ) { NetbeansActionMapping action = getProfileMappingForAction( actionName, project, replaceMap, fallback ); if (action != null) { return action; } return new NetbeansActionReader() { @Override protected String getRawMappingsAsString() { return M2Configuration.this.getRawMappingsAsString(); } @Override protected Reader performDynamicSubstitutions(Map replaceMap, String in) throws IOException { return M2Configuration.this.performDynamicSubstitutions(replaceMap, in); } }.getMappingForAction(reader, LOG, actionName, null, project, null, replaceMap); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy