blob: 50d9763695d9a14d092bcd9b82165e01761707b7 [file] [log] [blame]
/*
* 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.api.project;
import org.netbeans.spi.project.SourceGroupModifierImplementation;
import org.netbeans.spi.project.SourceGroupRelativeModifierImplementation;
/**
* <code>SourceGroupModifier</code> provides ways of create specific folders ({@link org.netbeans.api.project.SourceGroup} root folders)
* in case they don't exist, eg. cannot be retrieved from {@link org.netbeans.api.project.Sources}
* The project type supporting automated creation of {@link org.netbeans.api.project.SourceGroup} root folders needs to
* provide {@link org.netbeans.spi.project.SourceGroupModifierImplementation} in the project's lookup.
*
* @since org.netbeans.modules.projectapi 1.24
* @author mkleint
*/
public final class SourceGroupModifier {
private SourceGroupModifier() {
}
/**
* Creates a {@link org.netbeans.api.project.SourceGroup} in the given {@link org.netbeans.api.project.Project} of the given type and hint.
* Typically a type is a constant for java/groovy/ruby source roots and hint is a constant for main sources or test sources.
* Please consult specific APIs fro the supported types/hints. Eg. <code>JavaProjectConstants</code> for java related project sources.
*
* @param project
* @param type constant for type of sources
* @param hint
* @return the created SourceGroup or null
*/
public static final SourceGroup createSourceGroup(Project project, String type, String hint) {
assert project != null;
SourceGroupModifierImplementation impl = project.getLookup().lookup(SourceGroupModifierImplementation.class);
if (impl == null) {
return null;
}
return impl.createSourceGroup(type, hint);
}
/**
* Creates a source group associated to an existing one. In a project with multiple locations for sources or tests some of those locations
* can be more appropriate (or completely unrelated) to already existing specific sources. This variant of {@link #createSourceGroup(org.netbeans.api.project.Project, java.lang.String, java.lang.String)}
* allows to select appropriate locations, if the newly created {@code SourceGroup} should work in association with some existing one.
* <p>
* The source group will be created on location most similar to the provided {@code original} group. If {@code projectParts} are specified, the most matching
* location will be selected.
* <p>
* This feature is prototypically used in J2SE modular projects, where multiple locations exists for tests and sources, yet they are related by their owning module. Other
* project types may also partition project sources into logical groups, similar to modules.
* <p>
* Some (java) examples:
* <ul>
* <li>to create a source folder in project module, use <code>relativeTo(modulesGroup, "moduleName").createSourceGroup(..)</code>
* <li>to create a specific module root in project module, use <code>relativeTo(modulesGroup, "moduleName", "path-to-modules").createSourceGroup(...)</code>
* <li>to create a test folder for a specific source location, use <code>relativeTo(sourceLocation).createSourceGroup(...)</code>
* <li>or, if there are more test locations to choose, you can use <code>relativeTo(sourceLocation, "test2").createSourceGroup(...)</code>.
* </ul>
* @param project the project
* @param original the original SourceGroup, which the new one should be related to.
* @param type type of sources
* @param hint additional type hint
* @param projectParts optional; abstract location within the project.
* @return the creaed SourceGroup or {@code null}
* @since 1.68
*/
public static final SourceGroup createAssociatedSourceGroup(Project project, SourceGroup original, String type, String hint, String... projectParts) {
SourceGroupRelativeModifierImplementation relMod = project.getLookup().lookup(SourceGroupRelativeModifierImplementation.class);
if (relMod == null) {
return createSourceGroup(project, type, hint);
} else {
SourceGroupModifierImplementation impl = relMod.relativeTo(original, projectParts);
if (impl == null) {
return createSourceGroup(project, type, hint);
} else {
return impl.createSourceGroup(type, hint);
}
}
}
/**
* Creates a {@link org.netbeans.api.project.SourceGroupModifier.Future} object
* that is capable of lazily creating {@link org.netbeans.api.project.SourceGroup} in the given {@link org.netbeans.api.project.Project} of the given type and hint.
* Typically a type is a constant for java/groovy/ruby source roots and hint is a constant for main sources or test sources.
* Please consult specific APIs fro the supported types/hints. Eg. <code>JavaProjectConstants</code> for java related project sources.
* @param project
* @param type constant for type of sources
* @param hint
* @return Future instance that is capable of creating a SourceGroup or null
*/
public static final SourceGroupModifier.Future createSourceGroupFuture(Project project, String type, String hint) {
assert project != null;
SourceGroupModifierImplementation impl = project.getLookup().lookup(SourceGroupModifierImplementation.class);
if (impl == null) {
return null;
}
if (impl.canCreateSourceGroup(type, hint)) {
return new Future(impl, type, hint);
}
return null;
}
/**
* A wrapper class that is capable of lazily creating a {@link SourceGroup} instance.
*/
public static final class Future {
SourceGroupModifierImplementation impl;
private String hint;
private String type;
private Future(SourceGroupModifierImplementation im, String type, String hint) {
this.impl = im;
this.hint = hint;
this.type = type;
}
/**
* Create the instance of {@link SourceGroup} wrapped by
* this object.
* @return a source group
*/
public final SourceGroup createSourceGroup() {
return impl.createSourceGroup(type, hint);
}
/**
* The type of sources associated with the current instance.
* @return type constant for type of sources
*/
public String getType() {
return type;
}
/**
* The source hint associated with the current instance.
* @return hint constant for type of sources
*/
public String getHint() {
return hint;
}
}
}