/*******************************************************************************
* Copyright (c) 2012 The PDT Extension Group (https://github.com/pdt-eg)
* 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
******************************************************************************/
package org.pdtextensions.server.internal.web;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.osgi.service.prefs.BackingStoreException;
import org.pdtextensions.server.PEXServerPlugin;
import org.pdtextensions.server.web.IPhpWebFolder;
/**
* A storage using a settings file inside the projects root (.settings/org.pdtextensions.server.web.prefs).
*
* @author mepeisen
*
*/
public class SettingsPhpProjectStorage implements IWebProjectStorage {
private static final String PREFS_DEFAULT_WEB_ROOT = "defaultWebRoot"; //$NON-NLS-1$
private static final String PREFS_FOLDER_COUNT = "folderCount"; //$NON-NLS-1$
private static final String PREFS_FOLDER_CONTAINER = "folder.container."; //$NON-NLS-1$
private static final String PREFS_FOLDER_PATHNAME = "folder.pathName."; //$NON-NLS-1$
private static final String PREFS_QUALIFIER = "org.pdtextensions.server.webproject"; //$NON-NLS-1$
/** the settings filename */
public static final String SETTINGS_FILENAME = ".settings/org.pdtextensions.server.webproject.prefs"; //$NON-NLS-1$
/** eclipse project */
private IProject project;
/** the project default web folder. */
private IContainer defaultWebFolder;
/** the additional web folders. */
private List<WebFolder> folders = new ArrayList<WebFolder>();
private boolean prefsChanging = false;
/**
* The php project
* @param project
*/
public SettingsPhpProjectStorage(IProject project) throws BackingStoreException {
this.project = project;
this.reload();
}
public void reload() throws BackingStoreException {
if (!this.prefsChanging) {
this.folders.clear();
final ProjectScope scope = new ProjectScope(project);
final IEclipsePreferences prefs = scope.getNode(PREFS_QUALIFIER);
if (prefs.nodeExists(PREFS_DEFAULT_WEB_ROOT)) {
final String def = prefs.get(PREFS_DEFAULT_WEB_ROOT, null);
if (def.length() == 0) {
this.defaultWebFolder = this.project;
} else {
this.defaultWebFolder = this.project.getFolder(def);
}
} else {
this.defaultWebFolder = this.project;
}
if (prefs.nodeExists(PREFS_FOLDER_COUNT)) {
for (int i = 0; i < prefs.getInt(PREFS_FOLDER_COUNT, 0); i++) {
final String container = prefs.get(PREFS_FOLDER_CONTAINER + i, null);
final String pathName = prefs.get(PREFS_FOLDER_PATHNAME + i, null);
this.folders.add(new WebFolder(project.getFolder(container), pathName));
}
}
}
}
/**
* @see org.pdtextensions.server.internal.web.IWebProjectStorage#getDefaultWebFolder()
*/
@Override
public IContainer getDefaultWebFolder() {
return this.defaultWebFolder;
}
/**
* @see org.pdtextensions.server.internal.web.IWebProjectStorage#setDefaultWebFolder(org.eclipse.core.resources.IContainer)
*/
@Override
public void setDefaultWebFolder(IContainer folder) throws CoreException {
if (!folder.getProject().equals(this.project)) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Container not within target project")); //$NON-NLS-1$
}
this.prefsChanging = true;
try {
final ProjectScope scope = new ProjectScope(project);
final IEclipsePreferences prefs = scope.getNode(PREFS_QUALIFIER);
prefs.put(PREFS_DEFAULT_WEB_ROOT, folder.getProjectRelativePath().toString());
try {
prefs.flush();
} catch (BackingStoreException e) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Error while saving preferences", e)); //$NON-NLS-1$
}
this.defaultWebFolder = folder;
}
finally {
this.prefsChanging = false;
}
}
/**
* @see org.pdtextensions.server.internal.web.IWebProjectStorage#getWebFolders()
*/
@Override
public IPhpWebFolder[] getWebFolders() {
return this.folders.toArray(new IPhpWebFolder[this.folders.size()]);
}
/**
* @see org.pdtextensions.server.internal.web.IWebProjectStorage#createWebFolder(org.eclipse.core.resources.IContainer, java.lang.String)
*/
@Override
public IPhpWebFolder createWebFolder(IContainer folder, String pathName)
throws CoreException {
if (!folder.getProject().equals(this.project)) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Container not within target project")); //$NON-NLS-1$
}
if (!pathName.startsWith("/")) { //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Path name must start with /")); //$NON-NLS-1$
}
for (final WebFolder f : this.folders) {
if (f.getFolder().equals(folder)) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Duplicate container")); //$NON-NLS-1$
}
if (f.getPathName().equals(pathName)) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Duplicate path namne")); //$NON-NLS-1$
}
}
final WebFolder result = new WebFolder(folder, pathName);
this.folders.add(result);
this.saveFolders();
return result;
}
private void saveFolders() throws CoreException {
this.prefsChanging = true;
try {
final ProjectScope scope = new ProjectScope(project);
final IEclipsePreferences prefs = scope.getNode(PREFS_QUALIFIER);
prefs.put(PREFS_FOLDER_COUNT, String.valueOf(folders.size()));
for (int i = 0; i < folders.size(); i++) {
final WebFolder folder = this.folders.get(i);
prefs.put(PREFS_FOLDER_CONTAINER + i, folder.getFolder().getProjectRelativePath().toString());
prefs.put(PREFS_FOLDER_PATHNAME + i, folder.getPathName());
}
try {
prefs.flush();
} catch (BackingStoreException e) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Error while saving preferences", e)); //$NON-NLS-1$
}
}
finally {
this.prefsChanging = false;
}
}
/**
* @see org.pdtextensions.server.internal.web.IWebProjectStorage#removeWebFolder(org.pdtextensions.server.web.IPhpWebFolder)
*/
@Override
public void removeWebFolder(IPhpWebFolder folder) throws CoreException {
if (this.folders.remove(folder)) {
this.saveFolders();
}
}
private final class WebFolder implements IPhpWebFolder {
private IContainer folder;
private String pathName;
/**
* @param folder
* @param pathName
*/
public WebFolder(IContainer folder, String pathName) {
this.folder = folder;
this.pathName = pathName;
}
/**
* @see org.pdtextensions.server.web.IPhpWebFolder#getFolder()
*/
@Override
public IContainer getFolder() {
return this.folder;
}
/**
* @see org.pdtextensions.server.web.IPhpWebFolder#getPathName()
*/
@Override
public String getPathName() {
return this.pathName;
}
/**
* @see org.pdtextensions.server.web.IPhpWebFolder#set(org.eclipse.core.resources.IContainer, java.lang.String)
*/
@Override
public void set(IContainer folder, String pathName) throws CoreException {
if (!folder.getProject().equals(SettingsPhpProjectStorage.this.project)) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Container not within target project")); //$NON-NLS-1$
}
if (!pathName.startsWith("/")) { //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Path name must start with /")); //$NON-NLS-1$
}
for (final WebFolder f : SettingsPhpProjectStorage.this.folders) {
if (f.getFolder().equals(folder) && f != this) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Duplicate container")); //$NON-NLS-1$
}
if (f.getPathName().equals(pathName) && f != this) {
throw new CoreException(new Status(IStatus.ERROR, PEXServerPlugin.PLUGIN_ID, "Duplicate path namne")); //$NON-NLS-1$
}
}
this.folder = folder;
this.pathName = pathName;
saveFolders();
}
}
}