Issue #1138 Changed LocalizationFile.protectedFile from boolean to LocalizationLevel so the protected level is specified if the file is protected. That way the file browser knows what level the file can be copied or moved to. Made speed improvements to perspective when refreshing files and consolidated different ways of doing same thing. Made all localization actions check protected level when setting if enabled or not. Added tool tip to protected files to show they are protected in view.
Change-Id: Id6862f29f431dd79758e39282659a670fe3a1536 Former-commit-id: 1d5b8912fe38bd21496c7b9f4ba385e27d7dedcd
This commit is contained in:
parent
caff5053cb
commit
84658dd03a
24 changed files with 938 additions and 577 deletions
|
@ -35,7 +35,6 @@ import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel
|
|||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.LocalizationInternalFile;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
|
||||
import com.raytheon.uf.common.localization.msgs.AbstractUtilityCommand;
|
||||
import com.raytheon.uf.common.localization.msgs.AbstractUtilityResponse;
|
||||
|
@ -43,9 +42,6 @@ import com.raytheon.uf.common.localization.msgs.ListResponseEntry;
|
|||
import com.raytheon.uf.common.localization.msgs.ProtectedFileCommand;
|
||||
import com.raytheon.uf.common.localization.msgs.ProtectedFileResponse;
|
||||
import com.raytheon.uf.common.localization.msgs.UtilityRequestMessage;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.util.FileUtil;
|
||||
|
||||
/**
|
||||
|
@ -66,9 +62,6 @@ import com.raytheon.uf.common.util.FileUtil;
|
|||
*/
|
||||
|
||||
public class CAVELocalizationAdapter implements ILocalizationAdapter {
|
||||
private static transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(CAVELocalizationAdapter.class.getPackage().getName(),
|
||||
"WORKSTATION", "CAVE");
|
||||
|
||||
private static final LocalizationManager manager = LocalizationManager
|
||||
.getInstance();
|
||||
|
@ -198,7 +191,7 @@ public class CAVELocalizationAdapter implements ILocalizationAdapter {
|
|||
response.date = null;
|
||||
response.existsOnServer = false;
|
||||
response.fileName = fileName;
|
||||
response.isProtected = false;
|
||||
response.protectedLevel = null;
|
||||
File file = getPath(caveConfigBase, fileName);
|
||||
response.isDirectory = file != null && file.isDirectory();
|
||||
responses.add(response);
|
||||
|
@ -229,17 +222,6 @@ public class CAVELocalizationAdapter implements ILocalizationAdapter {
|
|||
}
|
||||
|
||||
manager.retrieve(file);
|
||||
if (file.isProtected()) {
|
||||
File f;
|
||||
try {
|
||||
f = file.getFile(false);
|
||||
f.setReadOnly();
|
||||
} catch (LocalizationException e) {
|
||||
// shouldn't happen since file was just retrieved
|
||||
statusHandler.handle(Priority.PROBLEM, "Error retrieving file",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -253,7 +235,6 @@ public class CAVELocalizationAdapter implements ILocalizationAdapter {
|
|||
@Override
|
||||
public boolean save(File localFile, LocalizationContext context,
|
||||
String fileName) throws LocalizationOpFailedException {
|
||||
|
||||
if (context.getLocalizationLevel().isSystemLevel()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Saving to the System Level, "
|
||||
|
@ -416,7 +397,7 @@ public class CAVELocalizationAdapter implements ILocalizationAdapter {
|
|||
ListResponse response = new ListResponse();
|
||||
response.context = context;
|
||||
response.isDirectory = configFile.isDirectory();
|
||||
response.isProtected = false;
|
||||
response.protectedLevel = null;
|
||||
response.existsOnServer = false;
|
||||
response.fileName = p;
|
||||
response.date = new Date(configFile.lastModified());
|
||||
|
@ -442,10 +423,13 @@ public class CAVELocalizationAdapter implements ILocalizationAdapter {
|
|||
response.existsOnServer = false;
|
||||
response.fileName = pfr.getPathName();
|
||||
response.isDirectory = locFile.isDirectory();
|
||||
response.isProtected = pfr.isProtectedFile();
|
||||
response.protectedLevel = pfr.getProtectedLevel();
|
||||
|
||||
if (!response.isProtected
|
||||
|| (response.context.getLocalizationLevel() == LocalizationLevel.BASE)) {
|
||||
if (response.protectedLevel == null
|
||||
|| response.context.getLocalizationLevel().compareTo(
|
||||
response.protectedLevel) <= 0) {
|
||||
// if not protected or protected level is less than/equal to
|
||||
// our level, add response
|
||||
responses.add(response);
|
||||
}
|
||||
}
|
||||
|
@ -486,7 +470,7 @@ public class CAVELocalizationAdapter implements ILocalizationAdapter {
|
|||
lr.isDirectory = entry.isDirectory();
|
||||
}
|
||||
lr.context = context;
|
||||
lr.isProtected = entry.isProtectedFile();
|
||||
lr.protectedLevel = entry.getProtectedLevel();
|
||||
lr.existsOnServer = entry.isExistsOnServer();
|
||||
return lr;
|
||||
}
|
||||
|
|
|
@ -91,12 +91,16 @@ public class LocalizationSaveAsPopulator extends CompoundContributionItem {
|
|||
protected IContributionItem[] getContributionItems() {
|
||||
MenuManager menuMgr = new MenuManager("SaveAs", "FileSaveAs");
|
||||
final boolean enabled;
|
||||
final LocalizationLevel protectedLevel;
|
||||
final IEditorPart active = EditorUtil.getActiveEditor();
|
||||
if (active != null
|
||||
&& active.getEditorInput() instanceof LocalizationEditorInput) {
|
||||
enabled = active.isDirty();
|
||||
protectedLevel = ((LocalizationEditorInput) active.getEditorInput())
|
||||
.getLocalizationFile().getProtectedLevel();
|
||||
} else {
|
||||
enabled = false;
|
||||
protectedLevel = null;
|
||||
}
|
||||
|
||||
LocalizationLevel[] levels = PathManagerFactory.getPathManager()
|
||||
|
@ -119,7 +123,9 @@ public class LocalizationSaveAsPopulator extends CompoundContributionItem {
|
|||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
return enabled
|
||||
&& (protectedLevel == null || level
|
||||
.compareTo(protectedLevel) <= 0);
|
||||
}
|
||||
|
||||
});
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.localization.perspective.view;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.localization.adapter.LocalizationPerspectiveAdapter;
|
||||
import com.raytheon.uf.viz.localization.filetreeview.PathData;
|
||||
|
||||
/**
|
||||
* Manager class for creating {@link PathData} objects for the localization path
|
||||
* extension point entries
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 7, 2012 mschenke Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class PathDataExtManager {
|
||||
|
||||
private static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(PathDataExtManager.class);
|
||||
|
||||
/** Localization path extension point id */
|
||||
private static final String PATH_DEFINITION_ID = "com.raytheon.uf.viz.localization.localizationpath";
|
||||
|
||||
private static final String APPLICATION_ATTR = "application";
|
||||
|
||||
private static final String NAME_ATTR = "name";
|
||||
|
||||
private static final String PATH_ATTR = "value";
|
||||
|
||||
private static final String TYPE_ATTR = "localizationType";
|
||||
|
||||
private static final String FILTER_ATTR = "extensionFilter";
|
||||
|
||||
private static final String ADAPTER_ATTR = "localizationAdapter";
|
||||
|
||||
private static final String RECURSIVE_ATTR = "recursive";
|
||||
|
||||
/** Default application name */
|
||||
private static final String DEFAULT_APPLICATION = "Uncategorized";
|
||||
|
||||
/** Default localization perspective adapter */
|
||||
private static final LocalizationPerspectiveAdapter DEFAULT_ADAPTER = new LocalizationPerspectiveAdapter();
|
||||
|
||||
public static Collection<PathData> getPathData() {
|
||||
List<PathData> pathData = new ArrayList<PathData>();
|
||||
IExtensionRegistry registry = Platform.getExtensionRegistry();
|
||||
IExtensionPoint point = registry.getExtensionPoint(PATH_DEFINITION_ID);
|
||||
if (point != null) {
|
||||
for (IExtension ext : point.getExtensions()) {
|
||||
for (IConfigurationElement element : ext
|
||||
.getConfigurationElements()) {
|
||||
PathData pd = new PathData();
|
||||
pd.setApplication(element.getAttribute(APPLICATION_ATTR));
|
||||
if (pd.getApplication() == null
|
||||
|| pd.getApplication().trim().isEmpty()) {
|
||||
pd.setApplication(DEFAULT_APPLICATION);
|
||||
}
|
||||
pd.setName(element.getAttribute(NAME_ATTR));
|
||||
if (pd.getName() == null || pd.getName().trim().isEmpty()) {
|
||||
statusHandler
|
||||
.handle(Priority.PROBLEM,
|
||||
"Skipping path extension entry with no name set");
|
||||
continue;
|
||||
}
|
||||
pd.setPath(element.getAttribute(PATH_ATTR));
|
||||
if (pd.getPath() == null) {
|
||||
statusHandler
|
||||
.handle(Priority.PROBLEM,
|
||||
"Skipping path extension entry with no path set");
|
||||
}
|
||||
pd.setFilter(element.getAttribute(FILTER_ATTR));
|
||||
String recurse = element.getAttribute(RECURSIVE_ATTR);
|
||||
pd.setRecursive(Boolean.parseBoolean(recurse));
|
||||
|
||||
pd.setType(LocalizationType.valueOf(element
|
||||
.getAttribute(TYPE_ATTR)));
|
||||
if (pd.getType() == null) {
|
||||
// Skip if bad localization type specified
|
||||
statusHandler.handle(
|
||||
Priority.PROBLEM,
|
||||
"Skipping path extension entry with name: "
|
||||
+ pd.getName() + " and path: "
|
||||
+ pd.getPath()
|
||||
+ " with invalid localiation type: "
|
||||
+ element.getAttribute(TYPE_ATTR));
|
||||
continue;
|
||||
}
|
||||
LocalizationPerspectiveAdapter adapter = DEFAULT_ADAPTER;
|
||||
try {
|
||||
if (element.getAttribute(ADAPTER_ATTR) != null) {
|
||||
adapter = (LocalizationPerspectiveAdapter) element
|
||||
.createExecutableExtension(ADAPTER_ATTR);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
statusHandler
|
||||
.handle(Priority.PROBLEM,
|
||||
"Skipping path with name: "
|
||||
+ pd.getName()
|
||||
+ " and path: "
|
||||
+ pd.getPath()
|
||||
+ " due to error constructing adapter: "
|
||||
+ t.getLocalizedMessage(), t);
|
||||
}
|
||||
pd.setAdapter(adapter);
|
||||
pathData.add(pd);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Could not find extension point ("
|
||||
+ PATH_DEFINITION_ID
|
||||
+ ") from the extension point registry");
|
||||
}
|
||||
return pathData;
|
||||
}
|
||||
}
|
|
@ -19,8 +19,6 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.localization.perspective.view.actions;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.action.ActionContributionItem;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
|
@ -127,8 +125,7 @@ public abstract class AbstractToAction extends Action implements IMenuCreator {
|
|||
protected void fillMenu(Menu menu) {
|
||||
LocalizationLevel[] levels = PathManagerFactory.getPathManager()
|
||||
.getAvailableLevels();
|
||||
Arrays.sort(levels, LocalizationLevel.REVERSE_COMPARATOR);
|
||||
for (int i = levels.length - 1; i >= 0; --i) {
|
||||
for (int i = 0; i < levels.length; ++i) {
|
||||
LocalizationLevel level = levels[i];
|
||||
if (level.isSystemLevel() == false) {
|
||||
new ActionContributionItem(new AbstractToInternalAction(level))
|
||||
|
@ -137,6 +134,26 @@ public abstract class AbstractToAction extends Action implements IMenuCreator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the action for this level is enabled. By default, checks if
|
||||
* the level is the same as the file level
|
||||
*
|
||||
* @param level
|
||||
* @return
|
||||
*/
|
||||
protected boolean isLevelEnabled(LocalizationLevel level) {
|
||||
if (level == file.getContext().getLocalizationLevel()) {
|
||||
String fileCtxName = file.getContext().getContextName();
|
||||
String levelCtxName = LocalizationManager.getContextName(level);
|
||||
if ((fileCtxName == null && levelCtxName == null)
|
||||
|| (fileCtxName != null && fileCtxName.equals(levelCtxName))) {
|
||||
// same context name
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract void run(LocalizationLevel level);
|
||||
|
||||
private class AbstractToInternalAction extends Action {
|
||||
|
@ -145,16 +162,7 @@ public abstract class AbstractToAction extends Action implements IMenuCreator {
|
|||
|
||||
public AbstractToInternalAction(LocalizationLevel level) {
|
||||
this.level = level;
|
||||
if (level == file.getContext().getLocalizationLevel()) {
|
||||
String fileCtxName = file.getContext().getContextName();
|
||||
String levelCtxName = LocalizationManager.getContextName(level);
|
||||
if ((fileCtxName == null && levelCtxName == null)
|
||||
|| (fileCtxName != null && fileCtxName
|
||||
.equals(levelCtxName))) {
|
||||
// same context name
|
||||
this.setEnabled(false);
|
||||
}
|
||||
}
|
||||
this.setEnabled(isLevelEnabled(level));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -63,11 +63,28 @@ public class CopyToAction extends AbstractToAction {
|
|||
protected ILocalizationService service;
|
||||
|
||||
public CopyToAction(LocalizationFile file, ILocalizationService service) {
|
||||
super(file.isProtected() ? "Copy To (Protected)" : "Copy To", file);
|
||||
setEnabled(file.isProtected() == false);
|
||||
super("Copy To", file);
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.localization.perspective.view.actions.AbstractToAction
|
||||
* #isLevelEnabled(com.raytheon.uf.common.localization.LocalizationContext.
|
||||
* LocalizationLevel)
|
||||
*/
|
||||
@Override
|
||||
protected boolean isLevelEnabled(LocalizationLevel level) {
|
||||
boolean enabled = super.isLevelEnabled(level);
|
||||
if (enabled && file.isProtected()) {
|
||||
// Ensure protected level is greater than copy to level
|
||||
enabled = file.getProtectedLevel().compareTo(level) >= 0;
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
|
|
@ -70,14 +70,35 @@ public class MoveFileAction extends CopyToAction {
|
|||
setEnabled(delete.isEnabled());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.localization.perspective.view.actions.AbstractToAction
|
||||
* #isLevelEnabled(com.raytheon.uf.common.localization.LocalizationContext.
|
||||
* LocalizationLevel)
|
||||
*/
|
||||
@Override
|
||||
protected boolean isLevelEnabled(LocalizationLevel level) {
|
||||
boolean enabled = super.isLevelEnabled(level);
|
||||
if (enabled && file.isProtected()) {
|
||||
// Ensure protected level is greater than copy to level
|
||||
enabled = file.getProtectedLevel().compareTo(level) >= 0;
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(LocalizationLevel level) {
|
||||
boolean choice = MessageDialog.openQuestion(
|
||||
page.getWorkbenchWindow().getShell(),
|
||||
"Move Confirmation",
|
||||
"Are you sure you want to move "
|
||||
+ LocalizationUtil.extractName(file.getName()) + " to "
|
||||
+ level + " replacing any existing file?");
|
||||
boolean choice = MessageDialog
|
||||
.openQuestion(
|
||||
page.getWorkbenchWindow().getShell(),
|
||||
"Move Confirmation",
|
||||
"Are you sure you want to move "
|
||||
+ LocalizationUtil.extractName(file.getName())
|
||||
+ " to "
|
||||
+ level
|
||||
+ " replacing any existing file and deleting this file?");
|
||||
if (choice) {
|
||||
IPathManager pm = PathManagerFactory.getPathManager();
|
||||
final LocalizationFile newFile = pm.getLocalizationFile(
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel
|
|||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.viz.localization.filetreeview.LocalizationFileEntryData;
|
||||
import com.raytheon.uf.viz.localization.filetreeview.LocalizationFileGroupData;
|
||||
import com.raytheon.uf.viz.localization.service.ILocalizationService;
|
||||
|
||||
|
@ -47,15 +48,35 @@ import com.raytheon.uf.viz.localization.service.ILocalizationService;
|
|||
|
||||
public class PasteFileAction extends CopyToAction {
|
||||
|
||||
LocalizationFileGroupData dataToCopyTo;
|
||||
private LocalizationFileGroupData dataToCopyTo;
|
||||
|
||||
private LocalizationLevel pasteToProtectedLevel;
|
||||
|
||||
public PasteFileAction(ILocalizationService service, LocalizationFile file,
|
||||
LocalizationFileGroupData data) {
|
||||
super(file, service);
|
||||
setText(file.isProtected() ? "Paste To (Protected)" : "Paste To");
|
||||
setText("Paste To");
|
||||
this.dataToCopyTo = data;
|
||||
// Grab the level this file is protected at (if any)
|
||||
for (LocalizationFileEntryData entry : dataToCopyTo.getChildrenData()) {
|
||||
pasteToProtectedLevel = entry.getFile().getProtectedLevel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setEnabled(file.isProtected() == false);
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.localization.perspective.view.actions.CopyToAction
|
||||
* #isLevelEnabled
|
||||
* (com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel
|
||||
* )
|
||||
*/
|
||||
@Override
|
||||
protected boolean isLevelEnabled(LocalizationLevel level) {
|
||||
return pasteToProtectedLevel == null
|
||||
|| level.compareTo(pasteToProtectedLevel) <= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.localization.perspective.view.actions;
|
||||
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.action.ActionContributionItem;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.action.IMenuCreator;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.viz.localization.perspective.view.FileTreeView;
|
||||
|
||||
/**
|
||||
* Action for generating menu items for hiding/showing localization levels in
|
||||
* the {@link FileTreeView}
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 6, 2012 mschenke Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class ShowLevelsAction extends Action implements IMenuCreator {
|
||||
|
||||
private FileTreeView view;
|
||||
|
||||
private Menu menu;
|
||||
|
||||
public ShowLevelsAction(FileTreeView view) {
|
||||
super("Show", IAction.AS_DROP_DOWN_MENU);
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMenuCreator getMenuCreator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.action.IMenuCreator#dispose()
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (menu != null) {
|
||||
menu.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets
|
||||
* .Control)
|
||||
*/
|
||||
@Override
|
||||
public Menu getMenu(Control parent) {
|
||||
if (menu != null) {
|
||||
menu.dispose();
|
||||
}
|
||||
|
||||
menu = new Menu(parent);
|
||||
|
||||
fillMenu(menu);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets
|
||||
* .Menu)
|
||||
*/
|
||||
@Override
|
||||
public Menu getMenu(Menu parent) {
|
||||
if (menu != null) {
|
||||
menu.dispose();
|
||||
}
|
||||
|
||||
menu = new Menu(parent);
|
||||
|
||||
fillMenu(menu);
|
||||
return menu;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void fillMenu(Menu menu) {
|
||||
// Use of LocalizationLevels.values() in this case should be okay since
|
||||
// we are setting a property to display all context names for the level,
|
||||
// doesn't matter if our local context for the level is set
|
||||
for (LocalizationLevel level : PathManagerFactory.getPathManager()
|
||||
.getAvailableLevels()) {
|
||||
ActionContributionItem aci = new ActionContributionItem(
|
||||
new ShowLevelInternalAction(level));
|
||||
aci.fill(menu, -1);
|
||||
}
|
||||
}
|
||||
|
||||
private class ShowLevelInternalAction extends Action {
|
||||
|
||||
private LocalizationLevel level;
|
||||
|
||||
public ShowLevelInternalAction(LocalizationLevel level) {
|
||||
super(level.name(), IAction.AS_CHECK_BOX);
|
||||
this.level = level;
|
||||
setChecked(view.isShown(level));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
view.toggleShowLevel(level);
|
||||
setChecked(view.isShown(level));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -121,7 +121,7 @@ public class ThinClientLocalizationAdapter extends CAVELocalizationAdapter
|
|||
ListResponse response = new ListResponse();
|
||||
response.context = context;
|
||||
response.isDirectory = localFile.isDirectory();
|
||||
response.isProtected = false;
|
||||
response.protectedLevel = null;
|
||||
response.existsOnServer = false;
|
||||
response.fileName = p;
|
||||
response.date = new Date(localFile.lastModified());
|
||||
|
@ -155,7 +155,7 @@ public class ThinClientLocalizationAdapter extends CAVELocalizationAdapter
|
|||
response.context = ctx;
|
||||
response.existsOnServer = false;
|
||||
response.fileName = fileName;
|
||||
response.isProtected = false;
|
||||
response.protectedLevel = null;
|
||||
File file = getPath(ctx, fileName);
|
||||
if (file == null) {
|
||||
response.isDirectory = false;
|
||||
|
|
|
@ -142,7 +142,12 @@ public class LocalizationEditorInput implements IFileEditorInput,
|
|||
*/
|
||||
@Override
|
||||
public String getToolTipText() {
|
||||
return localizationFile.getName();
|
||||
String tip = localizationFile.getName();
|
||||
if (localizationFile.isProtected()) {
|
||||
tip += " (Protected @ " + localizationFile.getProtectedLevel()
|
||||
+ ")";
|
||||
}
|
||||
return tip;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -99,4 +99,46 @@ public class FileTreeEntryData {
|
|||
return resource instanceof IFolder;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((path == null) ? 0 : path.hashCode());
|
||||
result = prime * result
|
||||
+ ((pathData == null) ? 0 : pathData.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
FileTreeEntryData other = (FileTreeEntryData) obj;
|
||||
if (path == null) {
|
||||
if (other.path != null)
|
||||
return false;
|
||||
} else if (!path.equals(other.path))
|
||||
return false;
|
||||
if (pathData == null) {
|
||||
if (other.pathData != null)
|
||||
return false;
|
||||
} else if (!pathData.equals(other.pathData))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,4 +62,40 @@ public class LocalizationFileEntryData extends FileTreeEntryData {
|
|||
return (IFile) super.getResource();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result
|
||||
+ ((file == null) ? 0 : file.getContext().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
LocalizationFileEntryData other = (LocalizationFileEntryData) obj;
|
||||
if (file == null) {
|
||||
if (other.file != null)
|
||||
return false;
|
||||
} else if (!file.getContext().equals(other.file.getContext()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -198,21 +198,6 @@ public class PathData {
|
|||
return application;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param element
|
||||
* the element to set
|
||||
*/
|
||||
public void setElement(IConfigurationElement element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the element
|
||||
*/
|
||||
public IConfigurationElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param recursive
|
||||
* the recursive to set
|
||||
|
|
|
@ -243,8 +243,8 @@ public class EDEXLocalizationAdapter implements ILocalizationAdapter {
|
|||
entry.fileName = fullPath.substring(fullPath.indexOf(basePath));
|
||||
entry.date = new Date(file.lastModified());
|
||||
|
||||
entry.isProtected = ProtectedFiles.getProtectedLevel(null,
|
||||
ctx.getLocalizationType(), entry.fileName) != null;
|
||||
entry.protectedLevel = ProtectedFiles.getProtectedLevel(null,
|
||||
ctx.getLocalizationType(), entry.fileName);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
|
|
@ -126,19 +126,16 @@ public class ProtectedFiles {
|
|||
*/
|
||||
public static LocalizationLevel getProtectedLevel(String localizedSite,
|
||||
LocalizationType type, String path) {
|
||||
// Check base first
|
||||
if (base == null) {
|
||||
return null;
|
||||
LocalizationLevel protectedLevel = null;
|
||||
if (localizedSite != null) {
|
||||
ProtectedFiles site = getSiteLevelFiles(localizedSite);
|
||||
protectedLevel = site.getProtectedLevelInternal(type, path);
|
||||
}
|
||||
LocalizationLevel level = base.getProtectedLevelInternal(type, path);
|
||||
|
||||
// If not protected in base file, check the site
|
||||
if (level == null && localizedSite != null) {
|
||||
ProtectedFiles files = getSiteLevelFiles(localizedSite);
|
||||
level = files.getProtectedLevelInternal(type, path);
|
||||
if (protectedLevel == null) {
|
||||
protectedLevel = base.getProtectedLevelInternal(type, path);
|
||||
}
|
||||
|
||||
return level;
|
||||
return protectedLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,11 +227,12 @@ public class ProtectedFiles {
|
|||
LocalizationLevel[] levels = PathManagerFactory.getPathManager()
|
||||
.getAvailableLevels();
|
||||
|
||||
for (LocalizationLevel level : levels) {
|
||||
String levelPath = level.toString().toUpperCase() + ":" + path;
|
||||
boolean isProtected = protectedFiles.contains(levelPath);
|
||||
|
||||
if (isProtected) {
|
||||
for (int i = levels.length - 1; i >= 0; --i) {
|
||||
// Search backwards so we get highest protected level in case of
|
||||
// duplicate entries at different levels
|
||||
LocalizationLevel level = levels[i];
|
||||
String levelPath = level.name() + ":" + path;
|
||||
if (protectedFiles.contains(levelPath)) {
|
||||
protectionLevel = level;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -255,20 +255,15 @@ public class UtilityManager {
|
|||
entry.setExistsOnServer(false);
|
||||
}
|
||||
|
||||
boolean isProtected = false;
|
||||
LocalizationLevel protectedLevel = ProtectedFiles
|
||||
.getProtectedLevel(localizedSite,
|
||||
context.getLocalizationType(), path);
|
||||
entry.setProtectedLevel(protectedLevel);
|
||||
|
||||
if (protectedLevel != null) {
|
||||
isProtected = true;
|
||||
}
|
||||
|
||||
entry.setProtectedFile(isProtected);
|
||||
// add to entry if not protected or we are requesting protected
|
||||
// version
|
||||
// version or levels below (BASE if SITE protected, etc)
|
||||
if (protectedLevel == null
|
||||
|| protectedLevel == context.getLocalizationLevel()) {
|
||||
|| context.getLocalizationLevel().compareTo(protectedLevel) <= 0) {
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
|
||||
import com.raytheon.edex.utility.ProtectedFiles;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.msgs.AbstractUtilityCommand;
|
||||
import com.raytheon.uf.common.localization.msgs.AbstractUtilityResponse;
|
||||
import com.raytheon.uf.common.localization.msgs.ListContextCommand;
|
||||
|
@ -76,13 +77,11 @@ public class UtilitySrv implements IRequestHandler<UtilityRequestMessage> {
|
|||
} else if (cmd instanceof ProtectedFileCommand) {
|
||||
ProtectedFileCommand castCmd = (ProtectedFileCommand) cmd;
|
||||
ProtectedFileResponse response = new ProtectedFileResponse();
|
||||
boolean isProtected = false;
|
||||
if (ProtectedFiles.getProtectedLevel(
|
||||
castCmd.getLocalizedSite(), castCmd.getContext()
|
||||
.getLocalizationType(), castCmd.getSubPath()) != null) {
|
||||
isProtected = true;
|
||||
}
|
||||
response.setProtectedFile(isProtected);
|
||||
LocalizationLevel protectedLevel = ProtectedFiles
|
||||
.getProtectedLevel(castCmd.getLocalizedSite(), castCmd
|
||||
.getContext().getLocalizationType(), castCmd
|
||||
.getSubPath());
|
||||
response.setProtectedLevel(protectedLevel);
|
||||
response.setPathName(castCmd.getSubPath());
|
||||
response.setContext(castCmd.getContext());
|
||||
responses.add(response);
|
||||
|
|
|
@ -214,10 +214,10 @@ public interface ILocalizationAdapter {
|
|||
public boolean isDirectory;
|
||||
|
||||
/**
|
||||
* defines if the file is protected, i.e. the file can not be overridden
|
||||
* at user or site level
|
||||
* defines the level the file is protected at, i.e. the file can not be
|
||||
* overridden at user or site level. null if not protected
|
||||
*/
|
||||
public boolean isProtected;
|
||||
public LocalizationLevel protectedLevel;
|
||||
|
||||
/** defines if the file exists on the server */
|
||||
public boolean existsOnServer;
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
|
||||
import com.raytheon.uf.common.localization.ILocalizationAdapter.ListResponse;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
|
@ -113,7 +114,7 @@ public class LocalizationFile implements Comparable<LocalizationFile> {
|
|||
private final String path;
|
||||
|
||||
/** Protection flag of file, if file cannot be overridden, it is protected */
|
||||
private boolean isProtected;
|
||||
private LocalizationLevel protectedLevel;
|
||||
|
||||
/** File changed observers */
|
||||
private Set<ILocalizationFileObserver> observers = new HashSet<ILocalizationFileObserver>();
|
||||
|
@ -142,7 +143,8 @@ public class LocalizationFile implements Comparable<LocalizationFile> {
|
|||
|
||||
LocalizationFile(ILocalizationAdapter adapter, LocalizationContext context,
|
||||
File file, Date date, String path, String checkSum,
|
||||
boolean isDirectory, boolean existsOnServer, boolean isProtected) {
|
||||
boolean isDirectory, boolean existsOnServer,
|
||||
LocalizationLevel protectedLevel) {
|
||||
this.adapter = adapter;
|
||||
this.context = context;
|
||||
this.file = file;
|
||||
|
@ -151,7 +153,7 @@ public class LocalizationFile implements Comparable<LocalizationFile> {
|
|||
this.isAvailableOnServer = existsOnServer;
|
||||
this.isDirectory = isDirectory;
|
||||
this.path = LocalizationUtil.getSplitUnique(path);
|
||||
this.isProtected = isProtected;
|
||||
this.protectedLevel = protectedLevel;
|
||||
LocalizationNotificationObserver.getInstance().addObservedFile(this);
|
||||
}
|
||||
|
||||
|
@ -167,7 +169,7 @@ public class LocalizationFile implements Comparable<LocalizationFile> {
|
|||
this.fileTimestamp = metadata.date;
|
||||
this.fileCheckSum = metadata.checkSum;
|
||||
this.isDirectory = metadata.isDirectory;
|
||||
this.isProtected = metadata.isProtected;
|
||||
this.protectedLevel = metadata.protectedLevel;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -406,7 +408,16 @@ public class LocalizationFile implements Comparable<LocalizationFile> {
|
|||
* @return true if file is protected and cannot be overridden
|
||||
*/
|
||||
public boolean isProtected() {
|
||||
return isProtected;
|
||||
return protectedLevel != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level the file is protected at, null otherwise
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LocalizationLevel getProtectedLevel() {
|
||||
return protectedLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -415,11 +426,6 @@ public class LocalizationFile implements Comparable<LocalizationFile> {
|
|||
* @throws LocalizationOpFailedException
|
||||
*/
|
||||
public boolean save() throws LocalizationOpFailedException {
|
||||
if (isProtected) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Saving of protected files is unsupported");
|
||||
}
|
||||
|
||||
String checksum = "";
|
||||
try {
|
||||
checksum = Checksum.getMD5Checksum(file);
|
||||
|
|
|
@ -231,7 +231,7 @@ public class PathManager implements IPathManager {
|
|||
file = new LocalizationFile(this.adapter, lr.context,
|
||||
local, lr.date, name, lr.checkSum,
|
||||
lr.isDirectory, lr.existsOnServer,
|
||||
lr.isProtected);
|
||||
lr.protectedLevel);
|
||||
availableFiles.put(file.getContext(), file);
|
||||
}
|
||||
fileCache.put(new LocalizationFileKey(lr.fileName,
|
||||
|
@ -301,7 +301,7 @@ public class PathManager implements IPathManager {
|
|||
entry.context, file, entry.date,
|
||||
entry.fileName, entry.checkSum,
|
||||
entry.isDirectory, entry.existsOnServer,
|
||||
entry.isProtected);
|
||||
entry.protectedLevel);
|
||||
fileCache.put(key, lf);
|
||||
}
|
||||
if (lf.exists()) {
|
||||
|
@ -314,7 +314,7 @@ public class PathManager implements IPathManager {
|
|||
entry.context, file, entry.date,
|
||||
entry.fileName, entry.checkSum,
|
||||
entry.isDirectory, entry.existsOnServer,
|
||||
entry.isProtected);
|
||||
entry.protectedLevel);
|
||||
if (lf.exists()) {
|
||||
files.add(lf);
|
||||
fileCache.put(key, lf);
|
||||
|
@ -476,7 +476,7 @@ public class PathManager implements IPathManager {
|
|||
lre.setDirectory(file.isDirectory());
|
||||
lre.setExistsOnServer(file.isAvailableOnServer());
|
||||
lre.setFileName(file.getName());
|
||||
lre.setProtectedFile(file.isProtected());
|
||||
lre.setProtectedLevel(file.getProtectedLevel());
|
||||
cacheObject.put(new SerializableKey(entry.getKey()), lre);
|
||||
}
|
||||
try {
|
||||
|
@ -514,7 +514,7 @@ public class PathManager implements IPathManager {
|
|||
lre.getFileName()), lre.getDate(),
|
||||
lre.getFileName(), lre.getChecksum(),
|
||||
lre.isDirectory(), lre.isExistsOnServer(),
|
||||
lre.isProtectedFile());
|
||||
lre.getProtectedLevel());
|
||||
}
|
||||
fileCache.put(
|
||||
new LocalizationFileKey(key.getFileName(), key
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.xml.bind.annotation.XmlElement;
|
|||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.serialization.ISerializableObject;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
|
@ -76,7 +77,7 @@ public class ListResponseEntry implements ISerializableObject {
|
|||
|
||||
@XmlAttribute
|
||||
@DynamicSerializeElement
|
||||
protected boolean protectedFile;
|
||||
protected LocalizationLevel protectedLevel;
|
||||
|
||||
@XmlAttribute
|
||||
@DynamicSerializeElement
|
||||
|
@ -91,14 +92,18 @@ public class ListResponseEntry implements ISerializableObject {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return true if the file is protected
|
||||
* @return the protectedLevel
|
||||
*/
|
||||
public boolean isProtectedFile() {
|
||||
return protectedFile;
|
||||
public LocalizationLevel getProtectedLevel() {
|
||||
return protectedLevel;
|
||||
}
|
||||
|
||||
public void setProtectedFile(boolean protectedFile) {
|
||||
this.protectedFile = protectedFile;
|
||||
/**
|
||||
* @param protectedLevel
|
||||
* the protectedLevel to set
|
||||
*/
|
||||
public void setProtectedLevel(LocalizationLevel protectedLevel) {
|
||||
this.protectedLevel = protectedLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.xml.bind.annotation.XmlAccessType;
|
|||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
|
||||
|
@ -47,14 +48,21 @@ public class ProtectedFileResponse extends AbstractUtilityResponse {
|
|||
|
||||
@XmlAttribute
|
||||
@DynamicSerializeElement
|
||||
private boolean protectedFile;
|
||||
private LocalizationLevel protectedLevel;
|
||||
|
||||
public boolean isProtectedFile() {
|
||||
return protectedFile;
|
||||
/**
|
||||
* @return the protectedLevel
|
||||
*/
|
||||
public LocalizationLevel getProtectedLevel() {
|
||||
return protectedLevel;
|
||||
}
|
||||
|
||||
public void setProtectedFile(boolean protectedFile) {
|
||||
this.protectedFile = protectedFile;
|
||||
/**
|
||||
* @param protectedLevel
|
||||
* the protectedLevel to set
|
||||
*/
|
||||
public void setProtectedLevel(LocalizationLevel protectedLevel) {
|
||||
this.protectedLevel = protectedLevel;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -28,7 +28,7 @@ class ListResponseEntry(object):
|
|||
self.date = None
|
||||
self.checksum = None
|
||||
self.directory = None
|
||||
self.protectedFile = None
|
||||
self.protectedLevel = None
|
||||
self.existsOnServer = None
|
||||
|
||||
def getFileName(self):
|
||||
|
@ -62,10 +62,13 @@ class ListResponseEntry(object):
|
|||
self.directory = directory
|
||||
|
||||
def getProtectedFile(self):
|
||||
return self.protectedFile
|
||||
return self.protectedLevel is not None
|
||||
|
||||
def setProtectedFile(self, protectedFile):
|
||||
self.protectedFile = protectedFile
|
||||
def getProtectedLevel(self):
|
||||
return self.protectedLevel
|
||||
|
||||
def setProtectedLevel(self, protectedLevel):
|
||||
self.protectedLevel = protectedLevel
|
||||
|
||||
def getExistsOnServer(self):
|
||||
return self.existsOnServer
|
||||
|
|
Loading…
Add table
Reference in a new issue