diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/CAVELocalizationAdapter.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/CAVELocalizationAdapter.java index 8cdd4b55b6..0bfb188ed8 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/CAVELocalizationAdapter.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/localization/CAVELocalizationAdapter.java @@ -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; } diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/ui/LocalizationSaveAsPopulator.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/ui/LocalizationSaveAsPopulator.java index 4ad8ba6eff..ad98fda076 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/ui/LocalizationSaveAsPopulator.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/ui/LocalizationSaveAsPopulator.java @@ -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); } }); diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java index 0e2fb1bf97..78e41d207a 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java @@ -23,6 +23,7 @@ import java.io.File; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -30,7 +31,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.TreeMap; import org.eclipse.compare.CompareUI; import org.eclipse.core.resources.IFile; @@ -43,12 +43,7 @@ import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; -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.Path; -import org.eclipse.core.runtime.Platform; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; @@ -64,10 +59,13 @@ import org.eclipse.swt.dnd.FileTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackAdapter; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; @@ -84,7 +82,6 @@ import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.PartInitException; -import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; import com.raytheon.uf.common.localization.FileUpdatedMessage; @@ -106,7 +103,6 @@ import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.uf.viz.localization.LocalizationEditorInput; import com.raytheon.uf.viz.localization.LocalizationPerspectiveUtils; -import com.raytheon.uf.viz.localization.adapter.LocalizationPerspectiveAdapter; import com.raytheon.uf.viz.localization.filetreeview.FileTreeEntryData; import com.raytheon.uf.viz.localization.filetreeview.LocalizationFileEntryData; import com.raytheon.uf.viz.localization.filetreeview.LocalizationFileGroupData; @@ -121,6 +117,7 @@ import com.raytheon.uf.viz.localization.perspective.view.actions.OpenAction; import com.raytheon.uf.viz.localization.perspective.view.actions.OpenWithAction; import com.raytheon.uf.viz.localization.perspective.view.actions.PasteFileAction; import com.raytheon.uf.viz.localization.perspective.view.actions.ShowAllAction; +import com.raytheon.uf.viz.localization.perspective.view.actions.ShowLevelsAction; import com.raytheon.uf.viz.localization.service.ILocalizationService; /** @@ -199,75 +196,36 @@ public class FileTreeView extends ViewPart implements IPartListener2, } - private static final String PATH_DEFINITION_ID = "com.raytheon.uf.viz.localization.localizationpath"; - - private static final LocalizationPerspectiveAdapter DEFAULT_ADAPTER = new LocalizationPerspectiveAdapter(); - + /** Flag for linking view to active editor */ private boolean linkWithEditor = true; + /** Determines what levels we should show in the view */ + private Set showSet = new HashSet(); + + /** Set for determining what leves we should display all contexts for */ private Set showAllSet = new HashSet(); + /** Cache of available contexts for each level */ private Map> contextMap = new HashMap>(); - /** - * The File Tree widget. - */ + /** The File Tree widget. */ private TreeViewer viewer; - /** Image map */ + /** Image map for TreeItem icons */ private Map imageMap = new HashMap(); - /** - * Director Game - */ - private Image dirImg; + /** TreeItem image icon for directories */ + private Image directoryImage; - /** - * Extension list - */ - private IExtension[] extensions; - - /** - * The wait mouse pointer. - */ + /** Waiting cursor */ private Cursor waitCursor = null; - /** - * The normal arrow mouse pointer. - */ - private Cursor arrowCursor = null; - + /** Last file selected for "Copy" */ private LocalizationFile copyFile = null; - /** Application map for root tree nodes */ - private Map> applicationMap = new TreeMap>(); - + /** Workspace project used to store links to localization files */ private IProject localizationProject; - public FileTreeView() { - super(); - localizationProject = ResourcesPlugin - .getWorkspace() - .getRoot() - .getProject( - com.raytheon.uf.viz.localization.Activator.LOCALIZATION_PROJECT); - dirImg = getImageDescriptor("directory.gif").createImage(); - - IExtensionRegistry registry = Platform.getExtensionRegistry(); - - IExtensionPoint point = registry.getExtensionPoint(PATH_DEFINITION_ID); - if (point != null) { - extensions = point.getExtensions(); - } else { - extensions = new IExtension[0]; - } - - Display display = PlatformUI.getWorkbench().getActiveWorkbenchWindow() - .getShell().getDisplay(); - waitCursor = display.getSystemCursor(SWT.CURSOR_WAIT); - arrowCursor = display.getSystemCursor(SWT.CURSOR_ARROW); - } - /** * @return the tree */ @@ -284,12 +242,24 @@ public class FileTreeView extends ViewPart implements IPartListener2, public void init(IViewSite site) throws PartInitException { super.init(site); + localizationProject = ResourcesPlugin + .getWorkspace() + .getRoot() + .getProject( + com.raytheon.uf.viz.localization.Activator.LOCALIZATION_PROJECT); + directoryImage = getImageDescriptor("directory.gif").createImage(); + Display display = site.getShell().getDisplay(); + waitCursor = display.getSystemCursor(SWT.CURSOR_WAIT); + site.getPage().addPartListener(this); LocalizationNotificationObserver.getInstance() .addGlobalFileChangeObserver(this); ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); + + // Show all levels by default + showSet.addAll(Arrays.asList(LocalizationLevel.values())); } /* @@ -300,8 +270,8 @@ public class FileTreeView extends ViewPart implements IPartListener2, @Override public void dispose() { super.dispose(); - if (dirImg.isDisposed() == false) { - dirImg.dispose(); + if (directoryImage.isDisposed() == false) { + directoryImage.dispose(); } for (Image img : imageMap.values()) { @@ -346,21 +316,57 @@ public class FileTreeView extends ViewPart implements IPartListener2, tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); viewer = new TreeViewer(tree); + // Tooltip listeners for showing tool tip for protected files + final String[] toolTip = new String[1]; + tree.addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseHover(MouseEvent e) { + Tree tree = getTree(); + TreeItem item = tree.getItem(new Point(e.x, e.y)); + if (item != null) { + LocalizationLevel protectedLevel = null; + if (item.getData() instanceof LocalizationFileEntryData) { + protectedLevel = ((LocalizationFileEntryData) item + .getData()).getFile().getProtectedLevel(); + } else if (item.getData() instanceof LocalizationFileGroupData) { + for (LocalizationFileEntryData entry : ((LocalizationFileGroupData) item + .getData()).getChildrenData()) { + protectedLevel = entry.getFile() + .getProtectedLevel(); + break; + } + } + if (protectedLevel != null) { + String tip = "Protected @ " + protectedLevel.name(); + tree.setToolTipText(tip); + toolTip[0] = tip; + } + } + } + }); + tree.addMouseMoveListener(new MouseMoveListener() { + @Override + public void mouseMove(MouseEvent e) { + if (toolTip[0] != null) { + getTree().setToolTipText(""); + toolTip[0] = null; + } + } + }); + tree.addListener(SWT.Expand, new Listener() { @Override public void handleEvent(Event event) { - populateNode((TreeItem) event.item); + setWaiting(); + try { + populateNode((TreeItem) event.item); + } finally { + setDoneWaiting(); + } } }); tree.addSelectionListener(new SelectionAdapter() { - /* - * (non-Javadoc) - * - * @see - * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse - * .swt.events.SelectionEvent) - */ @Override public void widgetSelected(SelectionEvent e) { Tree tree = getTree(); @@ -395,22 +401,24 @@ public class FileTreeView extends ViewPart implements IPartListener2, if (selections.length == 0) { return; } - TreeItem ti = selections[0]; - if (ti.getData() instanceof LocalizationFileEntryData) { - FileTreeEntryData data = (FileTreeEntryData) ti.getData(); - if (data instanceof LocalizationFileEntryData) { - new OpenAction( - getSite().getPage(), - new LocalizationFileEntryData[] { (LocalizationFileEntryData) data }) - .run(); - } - } else { - populateNode(ti); - if (ti.getExpanded() == false) { - ti.setExpanded(true); + setWaiting(); + try { + TreeItem ti = selections[0]; + if (ti.getData() instanceof LocalizationFileEntryData) { + LocalizationFileEntryData data = (LocalizationFileEntryData) ti + .getData(); + new OpenAction(getSite().getPage(), + new LocalizationFileEntryData[] { data }).run(); } else { - ti.setExpanded(false); + populateNode(ti); + if (ti.getExpanded() == false) { + ti.setExpanded(true); + } else { + ti.setExpanded(false); + } } + } finally { + setDoneWaiting(); } } }); @@ -469,6 +477,7 @@ public class FileTreeView extends ViewPart implements IPartListener2, mgr.add(linkAction); IMenuManager viewMenu = getViewSite().getActionBars().getMenuManager(); + viewMenu.add(new ShowLevelsAction(this)); viewMenu.add(new ShowAllAction(this)); viewMenu.add(new Separator()); viewMenu.add(linkAction); @@ -482,13 +491,18 @@ public class FileTreeView extends ViewPart implements IPartListener2, } /** - * Repopulates all tree items in the tree. + * Repopulates all expanded tree items in the tree. * * @param item */ private void repopulateTree(Tree tree) { - for (TreeItem item : tree.getItems()) { - repopulateTree(item); + setWaiting(); + try { + for (TreeItem item : tree.getItems()) { + repopulateTreeItem(item); + } + } finally { + setDoneWaiting(); } } @@ -497,58 +511,87 @@ public class FileTreeView extends ViewPart implements IPartListener2, * * @param item */ - private void repopulateTree(TreeItem item) { - repopulateTree(item, false); + private void repopulateTreeItem(TreeItem item) { + Tree tree = item.getParent(); + // Get set of selected data objects + Set selectionSet = new HashSet(); + buildSelectionSet(tree.getSelection(), selectionSet, item); + // Recursively repopulate + repopulateTreeItemRecursive(item); + if (item.isDisposed() == false) { + // If item wasn't removed, reselect items + List selected = new ArrayList(); + select(selected, selectionSet, item); + selected.addAll(Arrays.asList(tree.getSelection())); + tree.setSelection(selected.toArray(new TreeItem[selected.size()])); + } } - private void repopulateTree(TreeItem item, boolean force) { - if (item.getData() == null) { - return; - } else if (item.getData() instanceof LocalizationFileEntryData) { - IResource rsc = ((LocalizationFileEntryData) item.getData()) - .getResource(); - try { - rsc.refreshLocal(IResource.DEPTH_INFINITE, null); - } catch (CoreException e) { - statusHandler.handle(Priority.PROBLEM, - "Error refreshing file: " + e.getLocalizedMessage(), e); - } - return; - } - if (item.getData() instanceof LocalizationFileGroupData == false) { - for (TreeItem ti : item.getItems()) { - repopulateTree(ti, force); - } - } - - boolean removeEmpty = true; + private void repopulateTreeItemRecursive(TreeItem item) { if (item.getData() instanceof FileTreeEntryData) { + // These are directory nodes FileTreeEntryData data = (FileTreeEntryData) item.getData(); - if (data.hasRequestedChildren() || force) { - boolean wasExpanded = item.getExpanded(); + if (data instanceof LocalizationFileEntryData == false + && data.hasRequestedChildren()) { + // Item has been populated, refresh + Map expandMap = new HashMap(); + buildExpandedMap(expandMap, item); item.removeAll(); data.setRequestedChildren(false); - // We only want to remove empty nodes if we successfully - // populated the node (no errors) - removeEmpty = populateNode(item); - item.setExpanded(wasExpanded); + new TreeItem(item, SWT.NONE); + expand(expandMap, item); + } + } else { + for (TreeItem child : item.getItems()) { + repopulateTreeItemRecursive(child); } - } - - if (removeEmpty && item.getItemCount() == 0) { - removeEmptyNode(item); } } - /** - * @param item - */ - private void removeEmptyNode(TreeItem item) { - TreeItem parentItem = item.getParentItem(); - if (parentItem != null && parentItem.getItemCount() == 1) { - removeEmptyNode(parentItem); - } else { - item.dispose(); + private void buildSelectionSet(TreeItem[] selected, Set set, + TreeItem root) { + for (TreeItem selection : selected) { + if (selection == root) { + set.add(root.getData()); + break; + } + } + + for (TreeItem item : root.getItems()) { + buildSelectionSet(selected, set, item); + } + } + + private void buildExpandedMap(Map map, + TreeItem root) { + FileTreeEntryData data = (FileTreeEntryData) root.getData(); + if (data != null) { + map.put(data, root.getExpanded()); + for (TreeItem item : root.getItems()) { + buildExpandedMap(map, item); + } + } + } + + private void select(List selections, Set set, + TreeItem item) { + if (item.getData() != null) { + if (set.contains(item.getData())) { + selections.add(item); + } + } + for (TreeItem child : item.getItems()) { + select(selections, set, child); + } + } + + private void expand(Map map, TreeItem item) { + if (map.containsKey(item.getData()) && map.get(item.getData())) { + populateNode(item); + item.setExpanded(true); + for (TreeItem child : item.getItems()) { + expand(map, child); + } } } @@ -556,7 +599,7 @@ public class FileTreeView extends ViewPart implements IPartListener2, * Initial population of the tree. */ private void populateTree() { - List pathList = getPathData(); + Collection pathList = PathDataExtManager.getPathData(); for (PathData pd : pathList) { addPathDataTreeNode(pd); } @@ -568,34 +611,41 @@ public class FileTreeView extends ViewPart implements IPartListener2, * @param pd */ private void addPathDataTreeNode(PathData pd) { - if (pd.getApplication().contains(File.separator)) { + String application = pd.getApplication(); + String name = pd.getName(); + if (application.contains(File.separator) + || application.contains(IPathManager.SEPARATOR)) { statusHandler .handle(Priority.PROBLEM, "Problem adding " + pd.getApplication() - + " folder: Path names cannot contain file separator string"); + + " folder: Path names cannot contain path separator string"); return; } - if (pd.getName().contains(File.separator)) { + if (name.contains(File.separator) + || name.contains(IPathManager.SEPARATOR)) { statusHandler .handle(Priority.PROBLEM, "Problem adding " + pd.getName() - + " folder: Path names cannot contain file separator string"); + + " folder: Path names cannot contain path separator string"); return; } - String application = pd.getApplication(); - List itemList = null; - TreeItem root = null; + Tree tree = getTree(); + TreeItem applicationItem = null; + for (TreeItem item : tree.getItems()) { + if (application.equals(item.getText())) { + applicationItem = item; + } + } - if (applicationMap.containsKey(application) == false) { - itemList = new ArrayList(); - root = new TreeItem(getTree(), SWT.NONE, getInsertionIndex( - getTree().getItems(), application)); - root.setText(application); - root.setImage(getImage((String) null)); - applicationMap.put(application, itemList); + if (applicationItem == null) { + // Create tree item for application + applicationItem = new TreeItem(tree, SWT.NONE, getInsertionIndex( + tree.getItems(), application)); + applicationItem.setText(application); + applicationItem.setImage(directoryImage); // Create folder in project for application IFolder folder = localizationProject.getFolder(application); @@ -607,24 +657,21 @@ public class FileTreeView extends ViewPart implements IPartListener2, "Error creating application folder", e); } } - root.setData(folder); - } else { - itemList = applicationMap.get(application); - root = itemList.get(0).getParentItem(); + applicationItem.setData(folder); } FileTreeEntryData treeData = new FileTreeEntryData(pd, pd.getPath()); treeData.setName(pd.getName()); - TreeItem dataTypeItem = new TreeItem(root, SWT.NONE, getInsertionIndex( - root.getItems(), treeData.getName())); + TreeItem dataTypeItem = new TreeItem(applicationItem, SWT.NONE, + getInsertionIndex(applicationItem.getItems(), name)); dataTypeItem.setData(treeData); - dataTypeItem.setText(treeData.getName()); - dataTypeItem.setImage(getImage((String) null)); + dataTypeItem.setText(name); + dataTypeItem.setImage(directoryImage); + // Add empty item so we get ability to expand new TreeItem(dataTypeItem, SWT.NONE); - itemList.add(dataTypeItem); // Create folder for PathData - treeData.setResource(createFolder((IFolder) root.getData(), + treeData.setResource(createFolder((IFolder) applicationItem.getData(), treeData.getName())); } @@ -725,11 +772,11 @@ public class FileTreeView extends ViewPart implements IPartListener2, } } - // Add "Open" group - if (fileList.size() > 0) { + // Add "Open" group if all selected items have files + if (fileList.size() == selected.length) { mgr.add(new OpenAction(getSite().getPage(), fileDataList .toArray(new LocalizationFileEntryData[fileList.size()]))); - if (fileList.size() == 1 && selected.length == 1) { + if (fileList.size() == 1) { // add open with... LocalizationFileEntryData data = (LocalizationFileEntryData) selected[0] .getData(); @@ -780,31 +827,33 @@ public class FileTreeView extends ViewPart implements IPartListener2, mgr.add(new Action("Compare") { @Override public void run() { - loadCompare( - (LocalizationFileEntryData) selected[0].getData(), - (LocalizationFileEntryData) selected[1].getData()); + LocalizationFileEntryData left = (LocalizationFileEntryData) selected[0] + .getData(); + LocalizationFileEntryData right = (LocalizationFileEntryData) selected[1] + .getData(); + LocalizationCompareEditorInput editorInput = new LocalizationCompareEditorInput( + new LocalizationEditorInput(left.getFile(), left + .getResource()), + new LocalizationEditorInput(right.getFile(), right + .getResource())); + CompareUI.openCompareEditor(editorInput); } - @Override - public boolean isEnabled() { - if ((getTree().getSelection()[0].getData() instanceof LocalizationFileEntryData) - && (getTree().getSelection()[1].getData() instanceof LocalizationFileEntryData)) { - return true; - } - return false; - } }); mgr.add(new Separator()); } - if (selected.length == 1) { - mgr.add(new Action("Refresh") { - @Override - public void run() { - refresh(selected[0]); + mgr.add(new Action("Refresh") { + @Override + public void run() { + setWaiting(); + try { + refresh(selected); + } finally { + setDoneWaiting(); } - }); - } + } + }); if (selected.length == 1) { Object data = selected[0].getData(); @@ -825,81 +874,50 @@ public class FileTreeView extends ViewPart implements IPartListener2, * Refresh the selected tree items */ public void refreshSelected() { - TreeItem[] selected = getTree().getSelection(); - if (selected != null && selected.length == 1) { - refresh(selected[0]); + setWaiting(); + try { + refresh(getTree().getSelection()); + } finally { + setDoneWaiting(); } } - private void refresh(TreeItem refresh) { - refresh.getParent().getShell().setCursor(waitCursor); - TreeItem[] items = new TreeItem[] { refresh }; - if (refresh.getData() instanceof FileTreeEntryData == false) { - items = refresh.getItems(); - } - + /** + * Refreshes the TreeItems passed in + * + * @param items + */ + private void refresh(TreeItem... items) { for (TreeItem item : items) { - FileTreeEntryData data = (FileTreeEntryData) item.getData(); - IResource rsc = data.getResource(); - if (rsc instanceof IFile) { - try { - rsc.refreshLocal(IResource.DEPTH_INFINITE, null); - } catch (CoreException e) { - statusHandler.handle(Priority.PROBLEM, - "Error refreshing file", e); - } - } else { - boolean wasExpanded = item.getExpanded(); - List expanded = new ArrayList(); - if (wasExpanded) { - fillExpanded(item, expanded); - } - item.removeAll(); - data.setRequestedChildren(false); - populateNode(item); - item.setExpanded(wasExpanded); - for (FileTreeEntryData expand : expanded) { - TreeItem found = find( - expand.getPath(), - PathManagerFactory.getPathManager().getContext( - expand.getPathData().getType(), - LocalizationLevel.BASE), false); - if (found != null) { - populateNode(found); - recursiveExpand(found); + if (item.isDisposed() == false) { + // If item is disposed, it was a child of a previous item and + // already refreshed + if (item.getData() instanceof FileTreeEntryData == false) { + // Application level node, refresh children + refresh(item.getItems()); + } else { + FileTreeEntryData data = (FileTreeEntryData) item.getData(); + IResource rsc = data.getResource(); + if (rsc instanceof IFile) { + try { + rsc.refreshLocal(IResource.DEPTH_INFINITE, null); + } catch (CoreException e) { + statusHandler.handle(Priority.PROBLEM, + "Error refreshing file", e); + } + } else { + repopulateTreeItem(item); } } } } - - refresh.getParent().getShell().setCursor(arrowCursor); - } - - private void recursiveExpand(TreeItem item) { - if (item.getExpanded() == false) { - recursiveExpand(item.getParentItem()); - item.setExpanded(true); - } - } - - private boolean fillExpanded(TreeItem item, List expanded) { - boolean hasExpandedChildren = false; - for (TreeItem ti : item.getItems()) { - if (ti.getExpanded()) { - hasExpandedChildren = true; - if (!fillExpanded(ti, expanded)) { - expanded.add((FileTreeEntryData) ti.getData()); - } - } - } - return hasExpandedChildren; } /** - * Expand the given tree node requesting data as needed + * Populates the given tree node's child items requesting data as needed * * @param parentItem - * The TreeItem node to expand + * The TreeItem node to populate */ private boolean populateNode(TreeItem parentItem) { if (parentItem == null) { @@ -919,96 +937,94 @@ public class FileTreeView extends ViewPart implements IPartListener2, } // Remove all children to get rid of placeholder child - setWaitCursor(); + boolean checkName = !(data instanceof LocalizationFileGroupData); - try { - boolean checkName = !(data instanceof LocalizationFileGroupData); + PathData pd = data.getPathData(); + String path = data.getPath(); + String[] filter = pd.getFilter(); + boolean recursive = pd.isRecursive(); + LocalizationType type = pd.getType(); - PathData pd = data.getPathData(); - String path = data.getPath(); - String[] filter = pd.getFilter(); - boolean recursive = pd.isRecursive(); - LocalizationType type = pd.getType(); + IPathManager pathManager = PathManagerFactory.getPathManager(); - IPathManager pathManager = PathManagerFactory.getPathManager(); + // Request for base/site/user - // Request for base/site/user - - List searchContexts = new ArrayList( - Arrays.asList(pathManager.getLocalSearchHierarchy(type))); - - // Use of LocalizationLevels.values() in this case should be okay - // since - // we are requesting all possible context names for the level, - // doesn't - // matter if our local context for the level is set - LocalizationLevel[] levels = pathManager.getAvailableLevels(); - for (LocalizationLevel level : levels) { - if (showAllSet.contains(level)) { - Set contexts = contextMap.get(level); - if (contexts == null) { - contexts = new HashSet( - Arrays.asList(PathManagerFactory - .getPathManager().getContextList(level))); - contextMap.put(level, contexts); - } - String myContext = LocalizationManager - .getContextName(level); - - for (String context : contexts) { - if ((myContext != null && myContext.equals(context)) - || (myContext == null && context == null)) { - continue; - } - - LocalizationContext ctx = pathManager.getContext(type, - level); - ctx.setContextName(context); - searchContexts.add(ctx); - } - } + LocalizationContext[] searchHierarchy = pathManager + .getLocalSearchHierarchy(type); + List searchContexts = new ArrayList( + searchHierarchy.length); + for (LocalizationContext ctx : searchHierarchy) { + if (showSet.contains(ctx.getLocalizationLevel())) { + searchContexts.add(ctx); } + } - boolean success = false; - List currentList = new ArrayList(); - LocalizationFile[] files = pathManager.listFiles(searchContexts - .toArray(new LocalizationContext[searchContexts.size()]), - path, filter, false, !recursive); - if (files == null) { - statusHandler.handle(Priority.PROBLEM, - "Error getting list of files"); - } else { - if (parentItem.getItemCount() == 1 - && parentItem.getItems()[0].getData() == null) { - parentItem.removeAll(); + // Use of LocalizationLevels.values() in this case should be okay + // since we are requesting all possible context names for the level, + // doesn't matter if our local context for the level is set + LocalizationLevel[] levels = pathManager.getAvailableLevels(); + for (LocalizationLevel level : levels) { + if (showAllSet.contains(level) && showSet.contains(level)) { + Set contexts = contextMap.get(level); + if (contexts == null) { + contexts = new HashSet( + Arrays.asList(PathManagerFactory.getPathManager() + .getContextList(level))); + contextMap.put(level, contexts); } + String myContext = LocalizationManager.getContextName(level); - for (LocalizationFile file : files) { - if (checkName - && (file.getName().isEmpty() || data.getPath() - .equals(file.getName()))) { + for (String context : contexts) { + if ((myContext != null && myContext.equals(context)) + || (myContext == null && context == null)) { continue; } - if (file.exists()) { - currentList.add(file); - } - } - // Sort files using specific ordering... - Collections.sort(currentList, new FileTreeFileComparator()); - - if (data instanceof LocalizationFileGroupData) { - populateGroupDataNode(parentItem, currentList); - } else { - populateDirectoryDataNode(parentItem, currentList); + LocalizationContext ctx = pathManager.getContext(type, + level); + ctx.setContextName(context); + searchContexts.add(ctx); } - success = true; + } + } + + boolean success = false; + List currentList = new ArrayList(); + LocalizationFile[] files = pathManager.listFiles(searchContexts + .toArray(new LocalizationContext[searchContexts.size()]), path, + filter, false, !recursive); + if (files == null) { + statusHandler.handle(Priority.PROBLEM, + "Error getting list of files"); + } else { + if (parentItem.getItemCount() == 1 + && parentItem.getItems()[0].getData() == null) { + parentItem.removeAll(); } - return success; - } finally { - setArrowCursor(); + for (LocalizationFile file : files) { + if (checkName + && (file.getName().isEmpty() || data.getPath().equals( + file.getName()))) { + continue; + } + if (file.exists()) { + currentList.add(file); + } + } + + // Sort files using specific ordering... + Collections.sort(currentList, new FileTreeFileComparator()); + + if (data instanceof LocalizationFileGroupData) { + populateGroupDataNode(parentItem, currentList); + } else { + populateDirectoryDataNode(parentItem, currentList); + } + success = true; } + + return success; } private void populateDirectoryDataNode(TreeItem parentItem, @@ -1150,16 +1166,12 @@ public class FileTreeView extends ViewPart implements IPartListener2, applicableItems.add(item); } } - start = Math.max(start, 0); + start = Math.max(start, 0); int insert = getInsertionIndex( applicableItems .toArray(new TreeItem[applicableItems.size()]), treeData.getName()); - - if (insert == -1) { - return null; - } idx = start + insert; } @@ -1194,18 +1206,6 @@ public class FileTreeView extends ViewPart implements IPartListener2, return fileItem; } - /** - * Display the compare editor. - */ - private void loadCompare(LocalizationFileEntryData left, - LocalizationFileEntryData right) { - LocalizationCompareEditorInput editorInput = new LocalizationCompareEditorInput( - new LocalizationEditorInput(left.getFile(), left.getResource()), - new LocalizationEditorInput(right.getFile(), right - .getResource())); - CompareUI.openCompareEditor(editorInput); - } - /** * Get the ImageDescriptor for the provided file name. * @@ -1249,7 +1249,7 @@ public class FileTreeView extends ViewPart implements IPartListener2, */ private Image getImage(String filePath) { if (filePath == null) { - return dirImg; + return directoryImage; } ImageDescriptor desc = LocalizationPerspectiveUtils.getEditorRegistry() .getImageDescriptor(filePath); @@ -1263,72 +1263,10 @@ public class FileTreeView extends ViewPart implements IPartListener2, } return img; } else { - return dirImg; + return directoryImage; } } - /** - * Get the path data for the file tree for all open perspectives - * - * @return List of PathData objects - */ - private List getPathData() { - List pathList = new ArrayList(); - for (IExtension ext : extensions) { - IConfigurationElement[] config = ext.getConfigurationElements(); - for (IConfigurationElement element : config) { - if (element.getName().equals("path")) { - PathData pd = new PathData(); - pd.setName(element.getAttribute("name")); - pd.setPath(element.getAttribute("value")); - pd.setType(LocalizationType.valueOf(element - .getAttribute("localizationType"))); - if (pd.getType() == null) { - // Skip if bad localization type specified - statusHandler - .handle(Priority.PROBLEM, - "Skipping path with name: " - + pd.getName() - + " and path: " - + pd.getPath() - + " with invalid localiation type: " - + element - .getAttribute("localizationType")); - continue; - } - pd.setFilter(element.getAttribute("extensionFilter")); - pd.setApplication(element.getAttribute("application")); - LocalizationPerspectiveAdapter adapter = DEFAULT_ADAPTER; - try { - if (element.getAttribute("localizationAdapter") != null) { - adapter = (LocalizationPerspectiveAdapter) element - .createExecutableExtension("localizationAdapter"); - } - } 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); - - String recurse = element.getAttribute("recursive"); - if ((recurse != null) && recurse.equalsIgnoreCase("true")) { - pd.setRecursive(true); - } - pd.setElement(element); - - pathList.add(pd); - } - } - } - return pathList; - } - /** * Finds the first TreeItem in the tree which matches the localization file * (minus level). If file is a directory, will return TreeItem which @@ -1448,14 +1386,18 @@ public class FileTreeView extends ViewPart implements IPartListener2, } } - private void setWaitCursor() { - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell() - .setCursor(waitCursor); + /** + * Set the cursor for waiting + */ + private void setWaiting() { + getSite().getShell().setCursor(waitCursor); } - private void setArrowCursor() { - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell() - .setCursor(arrowCursor); + /** + * Sets the cursor back from waiting + */ + private void setDoneWaiting() { + getSite().getShell().setCursor(null); } /* @@ -1533,52 +1475,15 @@ public class FileTreeView extends ViewPart implements IPartListener2, VizApp.runAsync(new Runnable() { @Override public void run() { - TreeItem[] selections = getTree().getSelection(); - List files = new ArrayList(); - for (TreeItem item : selections) { - if (item.getData() instanceof LocalizationFileEntryData) { - LocalizationFileEntryData data = (LocalizationFileEntryData) item - .getData(); - files.add(data.getFile()); - } - } - TreeItem toRefresh = find(file, true); if (toRefresh != null) { - if (isParentOf(toRefresh, file)) { - repopulateTree(toRefresh); - } - } - - for (LocalizationFile file : files) { - selectFile(file); + refresh(toRefresh); } } }); } } - private boolean isParentOf(TreeItem item, LocalizationFile file) { - Object obj = item.getData(); - if (obj instanceof FileTreeEntryData) { - FileTreeEntryData data = (FileTreeEntryData) obj; - if (data instanceof LocalizationFileGroupData) { - return true; - } - - String[] parentParts = LocalizationUtil.splitUnique(data.getPath()); - String[] fileParts = LocalizationUtil.splitUnique(file.getName()); - if (fileParts.length > 1 - && parentParts.length > 0 - && fileParts[fileParts.length - 2] - .equals(parentParts[parentParts.length - 1])) { - return true; - } - } - return false; - } - - /** NO-OP Interface operations (Required to implement) */ /* * (non-Javadoc) * @@ -1586,9 +1491,9 @@ public class FileTreeView extends ViewPart implements IPartListener2, */ @Override public void setFocus() { + getTree().setFocus(); } - /** Editor operations **/ /* * (non-Javadoc) * @@ -1732,7 +1637,7 @@ public class FileTreeView extends ViewPart implements IPartListener2, if (file != null) { TreeItem item = find(file, false); if (item != null) { - repopulateTree(item); + refresh(item); } } } @@ -1776,16 +1681,28 @@ public class FileTreeView extends ViewPart implements IPartListener2, selectItem((IEditorReference) (getSite().getPage().getReference(editor))); } - public void toggleShowAllLevel(LocalizationLevel level) { - if (showAllSet.contains(level)) { - showAllSet.remove(level); + private void toggleSet(Set set, LocalizationLevel level) { + if (set.contains(level)) { + set.remove(level); } else { - showAllSet.add(level); + set.add(level); } repopulateTree(getTree()); } + public void toggleShowAllLevel(LocalizationLevel level) { + toggleSet(showAllSet, level); + } + + public void toggleShowLevel(LocalizationLevel level) { + toggleSet(showSet, level); + } + public boolean isAllShown(LocalizationLevel level) { return showAllSet.contains(level); } + + public boolean isShown(LocalizationLevel level) { + return showSet.contains(level); + } } diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/PathDataExtManager.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/PathDataExtManager.java new file mode 100644 index 0000000000..2052f40654 --- /dev/null +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/PathDataExtManager.java @@ -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 + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 7, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @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 getPathData() { + List pathData = new ArrayList(); + 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; + } +} diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/AbstractToAction.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/AbstractToAction.java index c1eefda2b0..0835ce8ca8 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/AbstractToAction.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/AbstractToAction.java @@ -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 diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/CopyToAction.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/CopyToAction.java index ed3c09063e..96c8754f46 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/CopyToAction.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/CopyToAction.java @@ -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) * diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/MoveFileAction.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/MoveFileAction.java index 3dc889ea50..8f35af4284 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/MoveFileAction.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/MoveFileAction.java @@ -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( diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/PasteFileAction.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/PasteFileAction.java index df8ba565dd..9a5c674565 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/PasteFileAction.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/PasteFileAction.java @@ -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; } /* diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/ShowLevelsAction.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/ShowLevelsAction.java new file mode 100644 index 0000000000..d6e99d23aa --- /dev/null +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/ShowLevelsAction.java @@ -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} + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 6, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @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)); + } + } +} diff --git a/cave/com.raytheon.uf.viz.thinclient/src/com/raytheon/uf/viz/thinclient/localization/ThinClientLocalizationAdapter.java b/cave/com.raytheon.uf.viz.thinclient/src/com/raytheon/uf/viz/thinclient/localization/ThinClientLocalizationAdapter.java index 73c8224a78..5877a64a21 100644 --- a/cave/com.raytheon.uf.viz.thinclient/src/com/raytheon/uf/viz/thinclient/localization/ThinClientLocalizationAdapter.java +++ b/cave/com.raytheon.uf.viz.thinclient/src/com/raytheon/uf/viz/thinclient/localization/ThinClientLocalizationAdapter.java @@ -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; diff --git a/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/LocalizationEditorInput.java b/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/LocalizationEditorInput.java index 2ac0a02761..44220927d5 100644 --- a/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/LocalizationEditorInput.java +++ b/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/LocalizationEditorInput.java @@ -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; } /* diff --git a/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/FileTreeEntryData.java b/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/FileTreeEntryData.java index 6ab0e92303..c3cd773cb9 100644 --- a/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/FileTreeEntryData.java +++ b/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/FileTreeEntryData.java @@ -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; + } + } diff --git a/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/LocalizationFileEntryData.java b/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/LocalizationFileEntryData.java index e5ad4832c5..b841c0f667 100644 --- a/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/LocalizationFileEntryData.java +++ b/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/LocalizationFileEntryData.java @@ -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; + } + } diff --git a/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/PathData.java b/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/PathData.java index 26f7a0f8c5..5c00613100 100644 --- a/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/PathData.java +++ b/cave/com.raytheon.viz.localization/src/com/raytheon/uf/viz/localization/filetreeview/PathData.java @@ -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 diff --git a/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/utility/EDEXLocalizationAdapter.java b/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/utility/EDEXLocalizationAdapter.java index 7066fc23ed..75684652dd 100644 --- a/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/utility/EDEXLocalizationAdapter.java +++ b/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/utility/EDEXLocalizationAdapter.java @@ -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; } diff --git a/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/utility/ProtectedFiles.java b/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/utility/ProtectedFiles.java index 03a1cdbc3a..6cfd33865f 100644 --- a/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/utility/ProtectedFiles.java +++ b/edexOsgi/com.raytheon.edex.common/src/com/raytheon/edex/utility/ProtectedFiles.java @@ -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; } diff --git a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/UtilityManager.java b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/UtilityManager.java index 656f85006a..ad6352841a 100644 --- a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/UtilityManager.java +++ b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/UtilityManager.java @@ -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); } } diff --git a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/UtilitySrv.java b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/UtilitySrv.java index 4ba0a7abeb..ee6b3a66bd 100644 --- a/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/UtilitySrv.java +++ b/edexOsgi/com.raytheon.edex.utilitysrv/src/com/raytheon/edex/services/UtilitySrv.java @@ -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 { } 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); diff --git a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/ILocalizationAdapter.java b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/ILocalizationAdapter.java index 263065721c..afd2678256 100644 --- a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/ILocalizationAdapter.java +++ b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/ILocalizationAdapter.java @@ -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; diff --git a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LocalizationFile.java b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LocalizationFile.java index 550a4d40ea..6ae591bc64 100644 --- a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LocalizationFile.java +++ b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/LocalizationFile.java @@ -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 { 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 observers = new HashSet(); @@ -142,7 +143,8 @@ public class LocalizationFile implements Comparable { 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 { 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 { 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 { * @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 { * @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); diff --git a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/PathManager.java b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/PathManager.java index ee3587cbe5..2c3334b1f1 100644 --- a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/PathManager.java +++ b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/PathManager.java @@ -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 diff --git a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/msgs/ListResponseEntry.java b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/msgs/ListResponseEntry.java index 67d1a9e29a..1a0130d2a3 100644 --- a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/msgs/ListResponseEntry.java +++ b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/msgs/ListResponseEntry.java @@ -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; } /** diff --git a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/msgs/ProtectedFileResponse.java b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/msgs/ProtectedFileResponse.java index b953bfe5c6..139a2bcc60 100644 --- a/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/msgs/ProtectedFileResponse.java +++ b/edexOsgi/com.raytheon.uf.common.localization/src/com/raytheon/uf/common/localization/msgs/ProtectedFileResponse.java @@ -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; } /* diff --git a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/localization/msgs/ListResponseEntry.py b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/localization/msgs/ListResponseEntry.py index 98a15cbfd1..f18051a432 100644 --- a/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/localization/msgs/ListResponseEntry.py +++ b/pythonPackages/dynamicserialize/dstypes/com/raytheon/uf/common/localization/msgs/ListResponseEntry.py @@ -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