All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.phoebus.applications.alarm.model.AlarmTreeItem Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2018-2021 Oak Ridge National Laboratory.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.phoebus.applications.alarm.model;

import static org.phoebus.applications.alarm.AlarmSystem.logger;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;

import org.phoebus.util.text.CompareNatural;

/** Base class for all nodes in the alarm tree
 *  @param  Type used for the alarm state
 *  @author Kay Kasemir
 */
@SuppressWarnings("nls")
abstract public class AlarmTreeItem
{
    /** Visible name of the item */
    private final String name;

    /** Parent node */
    protected volatile AlarmTreeItem parent;

    /** Sub-tree elements of this item
     *
     *  

For nodes, this is the thread-safe {@link CopyOnWriteArrayList} * and all entries are kept in sorted order based on the item's name. * *

For leaf, it's an empty list. */ protected final List> children; /** Full path name of this item. * Like parent it's final so that it can be computed once, * because it is used very often. */ private final String path_name; private List guidance = Collections.emptyList(); private List displays = Collections.emptyList(); private List commands = Collections.emptyList(); private List actions = Collections.emptyList(); /** Constructor for item or leaf * *

Will NOT add item to parent to allow complete * construction before then using addToParent * to register with parent. * * @param parent_path Path name of parent, null for root * @param name Name of this item * @param children {@link CopyOnWriteArrayList} for item, empty list for leaf * @see #addToParent(AlarmTreeItem) */ protected AlarmTreeItem(final String parent_path, final String name, final List> children) { // Original implementation set this.parent here and // registered with parent.children, but that could result in // parent.maximizeSeverity then fetching state of this item // while we're still inside the constructor and not fully initialized. // Construction thus became a 2-step process with need to explicitly // call addToParent(). this.name = name; this.children = children; path_name = AlarmTreePath.makePath(parent_path, name); } /** Add item to parent * @param parent Parent item, null for root */ public void addToParent(final AlarmTreeItem parent) { this.parent = parent; if (parent == null) return; // Keep sorted by inserting at appropriate index // Note that getChild(name) depends on this order! final int index = Collections.binarySearch(parent.children, this, (a, b) -> CompareNatural.compareTo(a.getName(), b.getName())); if (index < 0) parent.children.add(-index-1, this); else parent.children.add(index, this); } /** @return Name */ public final String getName() { return name; } /** @return Full path name to this item, including the item name itself */ public final String getPathName() { return path_name; } /** @return Parent item. null for root */ public AlarmTreeItem getParent() { return parent; } /** Detach item from parent: Remove from parent's list of children * @throws Error if parent didn't know about this child item */ public void detachFromParent() { final AlarmTreeItem p = parent; parent = null; logger.log(Level.FINE, "Detach " + getPathName() + " from parent"); if (p != null) if (! p.children.remove(this)) throw new Error("Corrupt alarm tree, " + p.getPathName() + " is not aware of " + getPathName()); } /** @return Child items */ public List> getChildren() { return children; } /** Locate child element by name. * @param name Name of child to locate. * @return Child with given name or null if not found. */ public AlarmTreeItem getChild(final String name) { // Binary search for name // Depends on nodes being in 'natural' order int low = 0, high = children.size()-1; while (low <= high) { final int mid = (low + high) >>> 1; final AlarmTreeItem val = children.get(mid); final int cmp = CompareNatural.compareTo(val.getName(), name); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return val; // key found } return null; } /** @return State */ abstract public STATE getState(); /** @param guidance Guidance entries * @return true if guidance was changed, false if no change */ public boolean setGuidance(final List guidance) { if (this.guidance.equals(guidance)) return false; this.guidance = guidance; return true; } /** @return Guidance */ public List getGuidance() { return guidance; } /** @param displays Displays entries * @return true if displays were changed, false if no change */ public boolean setDisplays(final List displays) { if (this.displays.equals(displays)) return false; this.displays = displays; return true; } /** @return Displays */ public List getDisplays() { return displays; } /** @param commands Command entries * @return true if commands were changed, false if no change */ public boolean setCommands(final List commands) { if (this.commands.equals(commands)) return false; this.commands = commands; return true; } /** @return Commands */ public List getCommands() { return commands; } /** @param actions Actions entries * @return true if actions were changed, false if no change */ public boolean setActions(final List actions) { if (this.actions.equals(actions)) return false; this.actions = actions; return true; } /** @return Actions */ public List getActions() { return actions; } @Override public String toString() { return getName(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy