blob: 903f37039f8dfb247ab8287b58e2753dcbec8288 [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.modules.javafx2.project.fxml;
import java.awt.Component;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JList;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.java.project.JavaProjectConstants;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.SourceGroup;
import org.netbeans.api.project.SourceGroupModifier;
import org.netbeans.spi.java.project.support.ui.PackageView;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
/**
* Helper class to handle Location (Source Root) and Package selection in FXML wizards
*
* @author Petr Somol
*/
public class SourceGroupSupport {
private List<SourceGroupProxy> groups = null;
private final String type;
private SourceGroupProxy currentSourceGroup = null;
private String currentPackageName = null;
private SourceGroupSupport parent = null;
private String currentFileName = null;
public SourceGroupSupport(@NonNull String type) {
this.type = type;
}
public String getType() {
return type;
}
/**
* Access to parent is used to take over the last visited directory etc.
* @param support
*/
public void setParent(SourceGroupSupport support) {
this.parent = support;
}
public SourceGroupSupport getParent() {
return parent;
}
// add
public void addSourceGroups(@NonNull SourceGroup[] sourceGroups) {
if(sourceGroups == null || sourceGroups.length == 0) {
return;
}
if(groups == null) {
groups = new ArrayList<SourceGroupProxy>();
}
for(int i = 0; i < sourceGroups.length; i++) {
groups.add(new SourceGroupProxy(sourceGroups[i]));
}
if(currentSourceGroup == null) {
currentSourceGroup = groups.get(0);
}
}
public void addSourceGroupProxy(@NonNull Project project, @NonNull String displayName, String[] packageProxy) {
if(packageProxy == null || packageProxy.length == 0) {
return;
}
if(groups == null) {
groups = new ArrayList<SourceGroupProxy>();
}
groups.add(new SourceGroupProxy(project, displayName, packageProxy));
if(currentSourceGroup == null) {
currentSourceGroup = groups.get(0);
}
}
// get
public int noOfSourceGroups() {
if(groups != null) {
return groups.size();
}
return 0;
}
public List<SourceGroupProxy> getSourceGroups() {
if(groups != null) {
return Collections.unmodifiableList(groups);
}
return null;
}
public File[] getSourceGroupsAsFiles() {
List<File> list = new ArrayList<File>();
for(SourceGroupProxy p : groups) {
list.add(FileUtil.toFile(p.getRootFolder()));
}
return list.toArray(new File[0]);
}
// get/set current
public void setCurrentSourceGroup(SourceGroupProxy current) {
this.currentSourceGroup = current;
}
public SourceGroupProxy getCurrentSourceGroup() {
return currentSourceGroup;
}
public void setCurrentPackageName(String current) {
this.currentPackageName = current;
}
public String getCurrentPackageName() {
return currentPackageName;
}
public void setCurrentFileName(String fileName) {
this.currentFileName = fileName;
}
public String getCurrentFileName() {
return currentFileName;
}
// get folders
public String getCurrentPackagePath() {
if(currentPackageName != null && currentSourceGroup != null) {
String packageNameDecorated = (currentPackageName.startsWith("/") || currentPackageName.startsWith(File.separator) ? "" : "/") + // NOI18N
currentPackageName
+ (currentPackageName.endsWith("/") || currentPackageName.endsWith(File.separator) || currentPackageName.length() == 0 ? "" : "/"); // NOI18N
if(currentSourceGroup.isReal()) {
return FileUtil.getFileDisplayName(currentSourceGroup.getRootFolder()) + packageNameDecorated;
}
return FileUtil.getFileDisplayName(currentSourceGroup.getRootFolder()) + "/<" + currentSourceGroup.getDisplayName() + ">" + packageNameDecorated; // NOI18N
}
return null;
}
public FileObject getCurrentSourceGroupFolder() {
if(currentSourceGroup != null) {
return currentSourceGroup.getRootFolder();
}
return null;
}
public FileObject getCurrentChooserFolder() {
FileObject folder = getCurrentPackageFolder(false);
if(folder == null) {
folder = getCurrentSourceGroupFolder();
}
return folder;
}
/**
* Returns current package as FileObject or null if it does not exist.
* if create==true, creates if does not exist (also creates SourceGroup if does not exist)
* @param create
* @return
*/
public FileObject getCurrentPackageFolder(boolean create) {
if(currentPackageName != null && currentSourceGroup != null) {
if(create == true && !currentSourceGroup.isReal()) {
SourceGroup created = SourceGroupModifier.createSourceGroup(currentSourceGroup.getProject(), getType(), JavaProjectConstants.SOURCES_HINT_MAIN);
if(created != null) {
for(SourceGroupProxy p : groups) {
if(!p.isReal()) {
p.setSourceGroup(created);
}
}
return getCurrentPackageFolder(create);
}
}
if(currentSourceGroup.isReal()) {
FileObject rootFolder = currentSourceGroup.getRootFolder();
FileObject folder = rootFolder.getFileObject(currentPackageName, ""); // NOI18Ns
if(folder == null && create) {
try {
folder = rootFolder;
StringTokenizer tk = new StringTokenizer(currentPackageName, "/."); // NOI18N
String name = null;
while (tk.hasMoreTokens()) {
name = tk.nextToken();
FileObject fo = folder.getFileObject(name, ""); // NOI18N
if (fo == null) {
folder = folder.createFolder(name);
break;
}
folder = fo;
}
while (tk.hasMoreTokens()) {
name = tk.nextToken();
folder = folder.createFolder(name);
}
} catch (IOException e) {
Exceptions.printStackTrace(e);
}
}
return folder;
}
}
return null;
}
/**
* Proxy to represent SourceGroups, to enable processing of non-existent packages
* (and thus to enable correct Cancel in dialogs).
*/
public static class SourceGroupProxy implements SourceGroup {
private Project project = null;
private SourceGroup sourceGroup = null;
private FileObject root = null;
private String name = "n/a"; // NOI18N
private String displayName = "n/a"; // NOI18N
private Icon iconTrue = null;
private Icon iconFalse = null;
private List<String> packageProxy = null;
public SourceGroupProxy(@NonNull SourceGroup sourceGroup) {
this.sourceGroup = sourceGroup;
}
public SourceGroupProxy(@NonNull Project project, @NonNull String displayName, String[] packageProxy) {
this.project = project;
this.root = project.getProjectDirectory();
this.displayName = displayName;
this.packageProxy = new ArrayList<String>();
this.packageProxy.addAll(Arrays.asList(packageProxy));
}
public boolean isReal() {
return sourceGroup != null;
}
public Project getProject() {
return project;
}
public void setSourceGroup(@NonNull SourceGroup sourceGroup) {
this.sourceGroup = sourceGroup;
}
public ComboBoxModel getPackagesComboBoxModel() {
if(sourceGroup != null) {
return PackageView.createListView(sourceGroup);
}
if(packageProxy != null) {
return new DefaultComboBoxModel(packageProxy.toArray(new String[0]));
}
return null;
}
@Override
public String toString() {
if(sourceGroup != null) {
return sourceGroup.toString();
}
return name + '/' + displayName;
}
@Override
public int hashCode() {
int hash = 5;
hash = 53 * hash + (this.sourceGroup != null ? this.sourceGroup.hashCode() : 0);
FileObject root = getRootFolder();
hash = 53 * hash + (root != null ? root.hashCode() : 0);
hash = 53 * hash + (this.name != null ? this.name.hashCode() : 0);
hash = 53 * hash + (this.displayName != null ? this.displayName.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final SourceGroupProxy other = (SourceGroupProxy) obj;
if(this.sourceGroup != null && other.sourceGroup != null) {
return this.sourceGroup.getRootFolder().getPath().equals(other.sourceGroup.getRootFolder().getPath());
}
if(this.sourceGroup == null && other.sourceGroup == null) {
return this.displayName.equals(other.displayName);
}
return false;
}
@Override
public FileObject getRootFolder() {
if(sourceGroup != null) {
return sourceGroup.getRootFolder();
}
return root;
}
@Override
public String getName() {
if(sourceGroup != null) {
return sourceGroup.getName();
}
return name;
}
@Override
public String getDisplayName() {
if(sourceGroup != null) {
return sourceGroup.getDisplayName();
}
return displayName;
}
@Override
public Icon getIcon(boolean opened) {
if(sourceGroup != null) {
return sourceGroup.getIcon(opened);
}
return opened ? iconTrue : iconFalse;
}
@Override
public boolean contains(FileObject file) {
if(sourceGroup != null) {
return sourceGroup.contains(file);
}
return false;
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
if(sourceGroup != null) {
sourceGroup.addPropertyChangeListener(listener);
}
}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
if(sourceGroup != null) {
sourceGroup.removePropertyChangeListener(listener);
}
}
}
/**
* Displays a {@link SourceGroup} in {@link #rootComboBox}.
*/
public static final class GroupListCellRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
String name;
Icon icon;
if (value == null) {
name = ""; //NOI18N
icon = null;
} else {
assert value instanceof SourceGroupProxy;
SourceGroupProxy g = (SourceGroupProxy) value;
name = g.getDisplayName();
icon = g.getIcon(false);
}
super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
setIcon(icon);
return this;
}
}
/**
* Returns source group that contains the file object, or null if no such exists in support
* @param support
* @param folder
* @return
*/
public static SourceGroupProxy getContainingSourceGroup(SourceGroupSupport support, FileObject folder) {
List<SourceGroupProxy> list = null;
if(folder != null) {
list = support.getSourceGroups();
for(SourceGroupProxy p : list) {
FileObject root = p.getRootFolder();
if (root != null && (root.equals(folder) || FileUtil.isParentOf(root, folder))) {
return p;
}
}
}
if(list != null && !list.isEmpty()) {
return list.get(0);
}
return null;
}
public static ComboBoxModel getWaitModel() {
return new DefaultComboBoxModel(
new String[]{
NbBundle.getMessage(SourceGroupSupport.class,
"LBL_ConfigureFXMLPanel_PackageName_PleaseWait") // NOI18N
});
}
}