package bluej.groupwork;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import bluej.Config;
import bluej.groupwork.ui.TeamSettingsDialog;
import bluej.pkgmgr.PkgMgrFrame;
import bluej.pkgmgr.Project;
import bluej.utility.Debug;
import bluej.utility.DialogManager;
import threadchecker.OnThread;
import threadchecker.Tag;
| This class is responsible for reading and writing the configuration files
| regarding teamwork settings. The files are team.defs, which is located in
| the top-level folder of a team project, and the bluej.properties
|
| @author fisker
|
@OnThread(Tag.FXPlatform)
public class TeamSettingsController
{
@OnThread(value = Tag.Any)
private static final ArrayList<TeamworkProvider> teamProviders;
static {
teamProviders = new ArrayList<>(2);
try {
teamProviders.add(loadProvider("bluej.groupwork.svn.SubversionProvider"));
}
catch (Throwable e) {
Debug.message("Failed to initialize Subversion: " + e.getClass().getName()
+ ": "+ e.getLocalizedMessage());
}
try {
teamProviders.add(loadProvider("bluej.groupwork.git.GitProvider"));
} catch (Throwable e) {
Debug.message("Failed to initialize Git: " + e.getClass().getName()
+ ": " + e.getLocalizedMessage());
}
}
| An enum with all current use server types.
|
public enum ServerType
{
Subversion,
Git
}
private static TeamworkProvider loadProvider(String name) throws Throwable
{
Class<?> c = Class.forName(name);
Object instance = c.getDeclaredConstructor().newInstance();
return (TeamworkProvider) instance;
}
private Project project;
private File projectDir;
private Properties teamProperties;
private TeamSettingsDialog teamSettingsDialog;
private TeamSettings settings;
private String password;
private File teamdefs;
private Repository repository;
| Construct a team settings controller for the given project.
|
public TeamSettingsController(Project project)
{
this.project = project;
this.projectDir = project.getProjectDir();
teamProperties = new Properties();
readSetupFile();
}
| Construct a team settings controller, not associated with
| any project initially. The supplied projectDir need not be the
| final project directory - it is just used as a working location
| until the project is set.
|
public TeamSettingsController(File projectDir)
{
this.projectDir = projectDir;
teamProperties = new Properties();
}
| Assign this team settings controller to a particular project.
| Once this is done, the repository settings can no longer be
| changed.
|
public void setProject(Project proj)
{
project = proj;
projectDir = proj.getProjectDir();
repository = null;
disableRepositorySettings();
}
| Get a list of the teamwork providers (Subversion, Git).
|
public List getTeamworkProviders()
{
return teamProviders;
}
| Get the teamwork provider by name (Subversion, Git).
|
| @param type The server type that we need to get its provider
| @return The teamwork provider for the type passed
|
public TeamworkProvider getTeamworkProvider(ServerType type)
{
return teamProviders.stream()
.filter(teamworkProvider -> teamworkProvider.getProviderName().equals(type.name()))
.findAny().get();
}
| Get the repository. Returns null if user credentials are required
| but the user chooses to cancel.
|
public Repository trytoEstablishRepository(boolean authRequired)
{
if (authRequired && password == null) {
if (!getTeamSettingsDialog().showAndWait().isPresent())
return null;
TeamSettings settings = teamSettingsDialog.getSettings();
if (repository == null) {
try {
repository = settings.getProvider().getRepository(projectDir, settings);
}
catch (UnsupportedSettingException e)
{
DialogManager.showErrorTextFX(teamSettingsDialog.asWindow(), e.getLocalizedMessage());
}
}
else {
repository.setPassword(settings);
}
}
else if (!authRequired && password == null) {
try {
return settings.getProvider().getRepository(projectDir, settings);
}
catch (UnsupportedSettingException e) {
DialogManager.showErrorTextFX(teamSettingsDialog.asWindow(), e.getLocalizedMessage());
}
}
else {
if (repository == null) {
try {
repository = settings.getProvider().getRepository(projectDir, settings);
}
catch (UnsupportedSettingException e) {
DialogManager.showErrorTextFX(teamSettingsDialog.asWindow(), e.getLocalizedMessage());
}
}
}
return repository;
}
| Initialize the repository and make sure that authentication details (username/password) have
| been provided.
|
public boolean initRepository()
{
return initRepository(true);
}
| Initialise the repository, with optional authentication details. This can be used to
| intialise the repository without opening the team settings dialog.
|
private boolean initRepository(boolean auth)
{
return trytoEstablishRepository(auth) != null;
}
| Get a list of files (and possibly directories) in the project which should be
| under version control management. This includes files which have been locally
| deleted since the last commit.
|
| @param includeLayout indicates whether to include the layout (bluej.pkg) files.
| (Note that locally deleted bluej.pkg files are always included).
|
public Set getProjectFiles(boolean includeLayout)
{
initRepository();
boolean versionsDirs = false;
if (repository != null) {
versionsDirs = repository.versionsDirectories();
}
Set<File> files = project.getFilesInProject(includeLayout, versionsDirs);
if (repository != null) {
repository.getAllLocallyDeletedFiles(files);
}
return files;
}
| Get a filename filter suitable for filtering out files which we don't want
| to be under version control.
|
| @param includeLayout A flag to indicate if layout files should be included or filtered out.
| @param includeDirectories A flag to indicate if directories should be included or filtered out.
|
public FileFilter getFileFilter(boolean includeLayout, boolean includeDirectories)
{
initRepository(false);
FileFilter repositoryFilter = null;
if (repository != null) {
repositoryFilter = repository.getMetadataFilter();
}
return new CodeFileFilter(getIgnoreFiles(), includeLayout, includeDirectories, projectDir, repositoryFilter);
}
| Read the team setup file in the top level folder of the project
|
private void readSetupFile()
{
teamdefs = new File(projectDir, "team.defs");
try {
teamProperties.load(new FileInputStream(teamdefs));
initSettings();
}
catch (FileNotFoundException e) {
}
catch (IOException e) {
e.printStackTrace();
}
}
| Checks if a project has a team.defs if it doesn't, then return false
| @param projDir File object representing the directory where team.defs is located.
| @return true if there is a valid vcs. false otherwise.
|
@OnThread(Tag.Any)
public static boolean isValidVCSfound(File projDir)
{
File teamDefs = new File(projDir, "team.defs");
Properties p = new Properties();
String providerName = null;
try {
p.load(new FileInputStream(teamDefs));
providerName = p.getProperty("bluej.teamsettings.vcs");
} catch (IOException e){
}
if (providerName != null) {
for (int index = 0; index < teamProviders.size(); index++) {
TeamworkProvider prov = (TeamworkProvider) teamProviders.get(index);
if (prov.getProviderName().equalsIgnoreCase(providerName)) {
return true;
}
}
}
return false;
}
private void initSettings()
{
String user = getPropString("bluej.teamsettings.user");
if (user == null) {
user = "";
}
String yourName = getPropString("bluej.teamsettings.yourName");
if (yourName == null){
yourName = "";
}
String yourEmail = getPropString("bluej.teamsettings.yourEmail");
if (yourEmail == null){
yourEmail = "";
}
String group = getPropString("bluej.teamsettings.groupname");
if (group == null) {
group = "";
}
TeamworkProvider provider = null;
String providerName = getPropString("bluej.teamsettings.vcs");
if (providerName != null) {
for (int index = 0; index < teamProviders.size(); index++) {
TeamworkProvider prov = (TeamworkProvider) teamProviders.get(index);
if (prov.getProviderName().equalsIgnoreCase(providerName)) {
provider = prov;
}
}
}
if (provider != null) {
settings = initProviderSettings(user, group, password, provider);
settings.setYourName(yourName);
settings.setYourEmail(yourEmail);
}
}
public TeamSettings initProviderSettings(String user, String group, String password,
TeamworkProvider provider) {
String keyBase = "bluej.teamsettings."
+ provider.getProviderName().toLowerCase() + ".";
String prefix = getPropString(keyBase + "repositoryPrefix");
String server = getPropString(keyBase + "server");
String protocol = getPropString(keyBase + "protocol");
return new TeamSettings(provider, protocol, server, prefix, group, user, password);
}
| Prepare for the deletion of a directory. For CVS, this involves moving
| the metadata elsewhere. Returns true if the directory should actually
| be deleted, or false if the version control system will delete it either
| immediately or at commit time.
|
public boolean prepareDeleteDir(File dir)
{
Repository repository = trytoEstablishRepository(false);
if (repository == null)
return false;
return repository.prepareDeleteDir(dir);
}
| Prepare a newly created directory for version control.
|
public void prepareCreateDir(File dir)
{
Repository repository = trytoEstablishRepository(false);
if (repository != null)
repository.prepareCreateDir(dir);
}
| Get the team settings dialog to edit these team settings.
|
public TeamSettingsDialog getTeamSettingsDialog()
{
if (teamSettingsDialog == null) {
teamSettingsDialog = new TeamSettingsDialog(PkgMgrFrame.getMostRecent().getFXWindow(), this);
disableRepositorySettings();
}
return teamSettingsDialog;
}
| Disable the repository fields in the team settings dialog if
| we have a project attached.
|
private void disableRepositorySettings()
{
if (teamSettingsDialog != null && project != null) {
teamSettingsDialog.disableRepositorySettings();
}
}
| Write the settings to team.defs in the project. It no project is known,
| nothing happens. Note that nothing is written to bluej.properties. That
| is handled by the Config class.
|
public void writeToProject()
{
if (projectDir == null) {
return;
}
File cfgFile = new File(projectDir + "/team.defs");
if (!cfgFile.exists()) {
addIgnoreFilePatterns(teamProperties);
}
try {
teamProperties.store(new FileOutputStream(cfgFile), null);
repository = null;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
| Add to the team properties the files we wish to ignore, like class files
| and ctxt files
| @param teamProperties
|
private void addIgnoreFilePatterns(Properties teamProperties)
{
teamProperties.put("bluej.teamsettings.ignore1", ".*\\.class");
teamProperties.put("bluej.teamsettings.ignore2", "bluej\\.pkh");
teamProperties.put("bluej.teamsettings.ignore3", "team\\.defs");
teamProperties.put("bluej.teamsettings.ignore4", ".*\\.ctxt");
teamProperties.put("bluej.teamsettings.ignore5", ".*\\~");
teamProperties.put("bluej.teamsettings.ignore6", ".*\\#");
teamProperties.put("bluej.teamsettings.ignore7", ".*\\#backup");
teamProperties.put("bluej.teamsettings.ignore8", "\\.DS_Store");
}
| Get the property by the name strname. If the property is present in
| the project, that value is returned. If not, bluej.properties and then
| bluej.defs are searched. If not found, null is returned.
| @param strname
| @return
|
public String getPropString(String strname)
{
String result = teamProperties.getProperty(strname);
if (result != null) {
return result;
}
result = Config.getPropString(strname, null);
return result;
}
public void setPropString(String key, String value)
{
if (key != null && value != null)
teamProperties.setProperty(key, value);
}
public void updateSettings(TeamSettings newSettings, boolean useAsDefault)
{
settings = newSettings;
String userKey = "bluej.teamsettings.user";
String userValue = settings.getUserName();
setPropString(userKey, userValue);
String yourNameKey = "bluej.teamsettings.yourName";
String yourNameValue = "";
if (teamSettingsDialog.getSettings().getProvider().needsName()){
yourNameValue = settings.getYourName();
setPropString(yourNameKey, yourNameValue);
}
String yourEmailKey = "bluej.teamsettings.yourEmail";
String yourEmailValue = "";
if (teamSettingsDialog.getSettings().getProvider().needsEmail()){
yourEmailValue = settings.getYourEmail();
setPropString(yourEmailKey, yourEmailValue);
}
String providerKey = "bluej.teamsettings.vcs";
String providerName = newSettings.getProvider()
.getProviderName().toLowerCase();
setPropString(providerKey, providerName);
String keyBase = "bluej.teamsettings."
+ providerName + ".";
String serverKey = keyBase + "server";
String serverValue = settings.getServer();
if (serverValue != null)
setPropString(serverKey, serverValue);
String prefixKey = keyBase + "repositoryPrefix";
String prefixValue = settings.getPrefix();
setPropString(prefixKey, prefixValue);
String protocolKey = keyBase + "protocol";
String protocolValue = settings.getProtocol();
setPropString(protocolKey, protocolValue);
String groupKey = "bluej.teamsettings.groupname";
String groupValue = settings.getGroup();
setPropString(groupKey, groupValue);
String useAsDefaultKey = "bluej.teamsettings.useAsDefault";
Config.putPropString(useAsDefaultKey,
Boolean.toString(useAsDefault));
String passValue = settings.getPassword();
setPasswordString(passValue);
if (repository != null) {
TeamSettings settings = getTeamSettingsDialog().getSettings();
repository.setPassword(settings);
}
if (useAsDefault) {
Config.putPropString(providerKey, providerName);
Config.putPropString(userKey, userValue);
if (teamSettingsDialog.getSettings().getProvider().needsName()){
Config.putPropString(yourNameKey, yourNameValue);
}
if (teamSettingsDialog.getSettings().getProvider().needsEmail()){
Config.putPropString(yourEmailKey, yourEmailValue);
}
else {
Config.putPropString(serverKey, serverValue);
Config.putPropString(prefixKey, prefixValue);
Config.putPropString(groupKey, groupValue);
Config.putPropString(protocolKey, protocolValue);
}
}
}
| In the first instance we don't want to store password.
| We want to ask the first time they want to try and perform operation
| We then store for the rest of the session. Over time we may want to provide
| some way of storing with relative security.
|
public String getPasswordString()
{
return password;
}
private void setPasswordString(String password)
{
this.password = password;
}
public boolean hasPasswordString()
{
return password != null;
}
| Gets the regular expressions in string form for the files we should ignore
| @return List containing Strings
|
public List getIgnoreFiles()
{
Iterator<Object> keys = teamProperties.keySet().iterator();
List<String> patterns = new LinkedList<String>();
while (keys.hasNext()){
String key = (String) keys.next();
if (key.startsWith("bluej.teamsettings.cvs.ignore")) {
patterns.add(teamProperties.getProperty(key));
}
if (key.startsWith("bluej.teamsettings.ignore")) {
patterns.add(teamProperties.getProperty(key));
}
}
return patterns;
}
public boolean hasProject()
{
return project != null;
}
public Project getProject()
{
return project;
}
| Method to get working copy version.
|
| @return version number. -1 if not applicable or not subversion.
|
public double getWorkingCopyVersion()
{
return settings.getProvider().getWorkingCopyVersion(projectDir);
}
public boolean isDVCS()
{
if (settings != null)
{
TeamworkProvider provider = settings.getProvider();
if (provider != null)
return provider.isDVCS();
}
return false;
}
}
top,
use,
map,
class TeamSettingsController
. loadProvider
. TeamSettingsController
. TeamSettingsController
. setProject
. getTeamworkProviders
. getTeamworkProvider
. trytoEstablishRepository
. initRepository
. initRepository
. getProjectFiles
. getFileFilter
. readSetupFile
. isValidVCSfound
. initSettings
. initProviderSettings
. prepareDeleteDir
. prepareCreateDir
. getTeamSettingsDialog
. disableRepositorySettings
. writeToProject
. addIgnoreFilePatterns
. getPropString
. setPropString
. updateSettings
. getPasswordString
. setPasswordString
. hasPasswordString
. getIgnoreFiles
. hasProject
. getProject
. getWorkingCopyVersion
. isDVCS
719 neLoCode
+ 63 LoComm