Class StoreCommands

  • All Implemented Interfaces:
    Logable, Commands, Serializable
    Direct Known Subclasses:
    SASCommands

    public abstract class StoreCommands
    extends CommonCommands
    This also has the machinery for parsing configurations since the user should be able to load one from the command line.

    Created by Jeff Gaynor
    on 5/20/13 at 3:22 PM

    See Also:
    Serialized Form
    • Method Detail

      • setSortable

        public void setSortable​(Sortable sortable)
      • getSortable

        protected Sortable getSortable()
      • isMonitored

        public boolean isMonitored()
      • showUpkeepHelp

        protected void showUpkeepHelp()
      • getPrompt

        public String getPrompt()
        Description copied from interface: Commands
        The prompt displayed to the user. This allows it to change based on context.
        Returns:
        java.lang.String
      • getStore

        public Store getStore()
      • setStore

        public void setStore​(Store store)
      • showUpdateHelp

        protected void showUpdateHelp()
      • showSerializeHelp

        protected void showSerializeHelp()
      • showDeserializeHelp

        protected void showDeserializeHelp()
      • deserialize

        public void deserialize​(InputLine inputLine)
      • search

        public void search​(InputLine inputLine)
      • printRS

        public boolean printRS​(InputLine inputLine,
                               List<Identifiable> values,
                               List<String> returnedAttributes,
                               List limits)
        If limits is empty or null, show everything. Limits contains the indices to show.
        Parameters:
        inputLine -
        values -
        returnedAttributes -
        limits -
        Returns:
      • getMapConverter

        protected MapConverter getMapConverter()
      • oldUpdate

        protected void oldUpdate​(InputLine inputLine)
                          throws Throwable
        Older version of update. Not nearly as full-featured but still useful, so keep it and in cases it is needed, just invoke it on behalf of the user.
        Parameters:
        inputLine -
        Throws:
        IOException
        Throwable
      • update

        public boolean update​(Identifiable identifiable)
                       throws IOException
        This is the workhorse method for the object that lets you edit the values. Generally this should do validation and checking so that updates to the store are not garbage.
        Parameters:
        identifiable -
        Returns:
        returns true if the passed object needs to be saved, false otherwise.
        Throws:
        IOException
      • update

        public boolean update​(Identifiable identifiable,
                              boolean doSave,
                              int magicNumber)
                       throws IOException
        Update the object. doSave if true means to prompt the user to save it (usually what you want). The magic number is for when you are over-riding this with some specific tweak.
        Parameters:
        identifiable -
        doSave -
        magicNumber -
        Returns:
        Throws:
        IOException
      • extraUpdates

        public abstract void extraUpdates​(Identifiable identifiable,
                                          int magicNumber)
                                   throws IOException
        This is a hook for extensions so they don't have to completely rewrite complex update(edu.uiuc.ncsa.security.core.Identifiable) methods. It will be invoked before update displays the completed item and saves it, allowing any properties not in the base class to be queried and saved.
        Parameters:
        identifiable -
        magicNumber -
        Throws:
        IOException
      • format

        protected abstract String format​(Identifiable identifiable)
        In listing operations, take the Identifiable argument and make a string version that a user can understand
        Parameters:
        identifiable -
      • longFormat

        protected int longFormat​(Identifiable identifiable)
        Give a long (multi-line) formatted object. This should allow users to see everything cleanly. This assumes the long format, not the verbose
        Parameters:
        identifiable -
        Returns:
        the width of the left field when formatting (for consistent look and feel in overrides).
      • longFormat

        protected int longFormat​(Identifiable identifiable,
                                 boolean isVerbose)
        Long formatting with the switch for verbose or not. If false, that means use the long format
        Parameters:
        identifiable -
        isVerbose -
        Returns:
        the width of the left field when formatting (for consistent look and feel in overrides).
      • hasEntries

        protected boolean hasEntries()
        Tell if the user has run the listAll command.
        Returns:
      • clearEntries

        protected void clearEntries()
        Clears the list of entries so next call will get it afresh
      • showCreateHelp

        protected void showCreateHelp()
      • create

        public void create​(InputLine inputLine)
                    throws IOException
        Creates a new item. The optional argument is the new identifier.
        Parameters:
        inputLine -
        Throws:
        IOException
      • createEntry

        protected Identifiable createEntry​(int magicNumber)
        Wraps the store create method. This can be overridden in certain cases (e.g. creating users) where special handling is needed.
        Returns:
      • getSerializationKeys

        protected SerializationKeys getSerializationKeys()
        Get the serialization keys for the main store.
        Returns:
      • actualCreate

        protected Identifiable actualCreate​(InputLine inputLine,
                                            int magicNumber)
                                     throws IOException
        does the actual creation and returns the created object. If you override create(InputLine), this is what does the actual work.
        Parameters:
        inputLine -
        magicNumber -
        Returns:
        Throws:
        IOException
      • setIDFromInputLine

        protected Identifiable setIDFromInputLine​(Identifiable x,
                                                  InputLine inputLine)
        if the user specified the new identifier on the command line, peel it off and use it.
        Parameters:
        x -
        inputLine -
        Returns:
      • preCreation

        protected Identifiable preCreation​(Identifiable identifiable,
                                           int magicNumber)
        How to customize different objects this command processor creates (e.g. creating ersatz clients as a special case with a flag). These are invoked right after creation, but before the object is saved, so you can just set properties or prompt the user for specific properties. Note that if the user elects to update(Identifiable) the properties, then in the course of that extraUpdates(Identifiable, int) will be invoked, so that is another location for the user to get prompted for properties.
        Parameters:
        identifiable -
        magicNumber -
        Returns:
      • hasID

        public boolean hasID()
      • getID

        public List<Identifier> getID()
        Mutators for sub classes
        Returns:
      • clear_id

        public void clear_id​(InputLine inputLine)
      • getIdentifierfromIndex

        protected Identifier getIdentifierfromIndex​(Object x)
        If there is a list of objects, this will try to ferret out the identifier for the object.
        Parameters:
        x -
        Returns:
      • get_id

        public void get_id​(InputLine inputLine)
      • findByIDOrRS

        protected FoundIdentifiables findByIDOrRS​(Store store,
                                                  String name)
        This will find an object in the given store assuming the name is an identifier. Failing that, it tries to find a result set with that name. If there is no such element, a null is returned, rather than raising an error, so you can, e.g. prompt the user or some such.

        This is used for positional argument, like

             link_clients my_rs foo:/bar/baz
         
        which allows the command to get the result set my_rs and iterate over it, applying the operation with the other argument.
        Parameters:
        name -
        Returns:
      • findItem

        protected FoundIdentifiables findItem​(InputLine inputLine,
                                              boolean allowResultSets)
                                       throws Throwable
        Resolves the first argument of a command line into either a unique identifier against the ambient store. The contract is that IF there is an ID set (with set_id(InputLine)) then use that. Otherwise, take the last argument of the input line and try to find that.

        Note: If there is no such item, such as an empty set, this will return a null. Therefore, either the result is a null or has at least one element.

        This removes the arguments for this from the InputLine since that might mess up parsing it later. Properly, if this is needed for a command, it should be called as early as practical.

        Parameters:
        inputLine -
        Returns:
        Throws:
        Throwable
      • findItem

        protected FoundIdentifiables findItem​(Store store,
                                              InputLine inputLine,
                                              boolean allowResultSets)
                                       throws Throwable
        General case for finding items from a store. Pass in the store.
        Parameters:
        store -
        inputLine -
        allowResultSets -
        Returns:
        Throws:
        Throwable
      • showLSHelp

        protected void showLSHelp()
      • hasId

        protected boolean hasId()
      • showSizeHelp

        protected void showSizeHelp()
      • size

        public void size​(InputLine inputLine)
      • formatLongLine

        protected String formatLongLine​(String leftSide,
                                        String rightSide,
                                        int leftColumWidth,
                                        boolean isVerbose)
        Gets a consistent look and feel. If you have to override longFormat(Identifiable) and add your own entries, use this.
        Parameters:
        leftSide -
        rightSide -
        leftColumWidth -
        Returns:
      • longFormat

        protected int longFormat​(Identifiable identifiable,
                                 List<String> keySubset,
                                 boolean isVerbose)
        Prints a restricted set of keys from the first argument. Note that a missing or empty subset means print everything. The output is key values in a readable format using StringUtils.formatMap(Map, List, boolean, boolean, int, int, boolean)
        Parameters:
        identifiable - object to print
        keySubset - list of keys to restrict to
        isVerbose - multi-line output, otherwise only a single line, possibly truncated, per property is shown
        Returns:
      • showSearchHelp

        protected void showSearchHelp()
      • showSearchHelpExamples

        protected void showSearchHelpExamples()
      • getAndCheckKeyArg

        protected String getAndCheckKeyArg​(InputLine inputLine)
        resolves key shorthand of >key_name or -key key_name returns null if no such key OR if it is not valid in the key list. Does not remove the argument from the inputLine!
        Parameters:
        inputLine -
        Returns:
      • getKeyArg

        protected String getKeyArg​(InputLine inputLine,
                                   boolean removeIt)
        Just gets the key argument or null if not present. This does no checking if the key that is found is valid for the store.
        Parameters:
        inputLine -
        removeIt -
        Returns:
      • showCommandLineSwitchesHelp

        protected void showCommandLineSwitchesHelp()
      • showKeyShorthandHelp

        protected void showKeyShorthandHelp()
      • doCopy

        protected Identifier doCopy​(Identifiable source,
                                    Identifier targetId,
                                    boolean useRandomID)
        Do the copy. Note that if useRandomID is true, targetID is ignored,
        Parameters:
        source -
        targetId -
        useRandomID -
      • processList

        protected List processList​(InputLine inputLine,
                                   String key)
                            throws Exception
        A placeholder. StoreCommands2 in OA4MP does this with QDL, but that dependency here would create a compilation circularity.

        This looks for key [...] and returns a list for what's between the []. If there is no such list, a null is returned. (E.g. the key is missing)

        Contract is that the input line will have this entry removed and will be reparsed. This is to prevent bad parsing later.

        Parameters:
        inputLine -
        key -
        Returns:
        Throws:
        Exception
      • rangeHelpSnippet

        protected String rangeHelpSnippet()
      • showResultSetHelp

        protected void showResultSetHelp()
      • showEntrySubset

        protected void showEntrySubset​(Identifiable identifiable,
                                       List<String> keys,
                                       boolean isVerbose)
        Shows a subset of an entry.
        Parameters:
        identifiable -
        keys -
        isVerbose -
      • showEntry

        protected boolean showEntry​(Identifiable identifiable,
                                    String key,
                                    boolean isVerbose)
        Show the value of a single property from an entry.
        Parameters:
        identifiable -
        key -
        isVerbose -
      • hasKey

        protected boolean hasKey​(String key)
      • toXMLMap

        protected XMLMap toXMLMap​(Identifiable identifiable)
        Once an object is found in the store, convert it to JSON so that the properties may be accessed in a canonical way. This lets us take any identifiable object and manipulate its properties without knowing anything else about it.
        Parameters:
        identifiable -
        Returns:
      • fromXMLMap

        protected Identifiable fromXMLMap​(XMLMap map)
        Take the updated values for the object and return a new, updated object. This does not store it, so you have to do that if you want to keep the changes.
        Parameters:
        map -
      • inputJSON

        protected net.sf.json.JSONObject inputJSON​(net.sf.json.JSONObject oldJSON,
                                                   String key)
                                            throws IOException
        Allows for entering a new JSON object. This permits multi-line entry so formatted JSON can be cut and pasted into the command line (as long as there are no blank lines). This will validate the JSON, print out a message and check that you want to keep the new JSON. Note that you cannot overwrite the value of a configuration at this point mostly as a safety feature. So hitting return or /exit will have the same effect of keeping the current value.
        Parameters:
        oldJSON -
        Returns:
        null if the input is terminated (so retain the old object)
        Throws:
        IOException
      • multiLineInput

        protected String multiLineInput​(String oldValue,
                                        String key)
                                 throws IOException
        For entering muli-line strings (includes JSON).
        Parameters:
        oldValue - may be null if a new value
        key - used for constructing prompts.
        Returns:
        Throws:
        IOException
      • addEntry

        protected void addEntry​(Identifiable identifiable,
                                net.sf.json.JSON jjj)
        Add to an existing entry.
        Parameters:
        identifiable -
        jjj -
      • updateSingleValue

        protected Object updateSingleValue​(XMLMap map,
                                           String key)
                                    throws IOException
        Update a single value for a key, prompting the user for each value. This returns the value the user supplied
        Parameters:
        map -
        key -
        Returns:
        Throws:
        IOException
      • updateSingleValue

        protected net.sf.json.JSONArray updateSingleValue​(String key,
                                                          net.sf.json.JSONArray currentValue)
                                                   throws IOException
        Throws:
        IOException
      • getArgList

        protected List<String> getArgList​(InputLine inputLine)
        Deprecated.
        Slightly special case. This will look on the input line and extract a list of the form
             [a,b,c,...]
         
        So to avoid having a lot of parsing (and the fact that there is pretty much at most one array per line) this will take everything between [ ] and try to turn it in to a list. The alternative would be make the list syntax have to conform to InputLine's fairly primitive system of checking for flags.
        Parameters:
        inputLine -
        Returns:
      • getTempDir

        protected File getTempDir()
      • showArchiveHelp

        protected void showArchiveHelp()
      • loadQDLScript

        protected net.sf.json.JSONObject loadQDLScript​(net.sf.json.JSONObject currentConfig)
                                                throws IOException
        The contract is that this gets the entire current config and updates exactly the bits relating to QDL. This is then saved elsewhere.
        Parameters:
        currentConfig -
        Returns:
        Throws:
        IOException
      • showListKeysHelp

        protected void showListKeysHelp​(InputLine inputLine)
      • showLSHelp3

        protected void showLSHelp3()
      • showRMHelp

        protected void showRMHelp()
      • rmCleanup

        protected void rmCleanup​(FoundIdentifiables identifiable)
        Called if there is additional clean up needed. For instance, removing a client requires removing its approval record. The contract states that this is called after the objects have been removed from the main store.
        Parameters:
        identifiable -
      • doChangeID

        public StoreCommands.ChangeIDRecord doChangeID​(Identifiable identifiable,
                                                       Identifier newID,
                                                       boolean updatePermissions)
        Does the work of changing the ID for an object. This returns the state object from basic changes (so the object and it runs the updateStorePermissions(Identifier, Identifier, boolean) method, which you should override as needed. A typical use would be to change the ID's for a client, then use the returned record to change the approval record.

        Note:This is invoked after the changes to the base store items have been saved.

        Parameters:
        identifiable -
        newID -
        updatePermissions -
        Returns:
      • isBadID

        protected boolean isBadID​(URI uri)
      • findSingleton

        protected Identifiable findSingleton​(InputLine inputLine,
                                             String errorMessage)
                                      throws Throwable
        Does all the checks for a command that accepts a single store object. Throws an exception if not found. Note that this returns the object from the store
        Parameters:
        inputLine -
        Returns:
        Throws:
        Throwable
      • printIndexHelp

        protected void printIndexHelp​(boolean singletonsOnly)
      • extractRawList

        protected String extractRawList​(InputLine inputLine,
                                        String key)
        Assumes there is a key and the original line is of the form -key [x, y, ... ]. *If the user has a more complex list they can terminate it with LIST_EOL_MARKER, e.g.
             my_command -foo -my_list [3, 5, -1] !! -other_flag fnord
         

        Tells this function that everything from -my_list to !! is a single expression.

        Otherwise, this extracts everything between the [ and ] inclusive (most common case). It then truncates the original line and reparses it. This allows for the "whittle while you work" approach to input lines.

        Note that there is a call for getting a list, InputLine.getArgList(String) which does this, but with very simple logic. The difference is that the processList(InputLine, String) function in this class should allow for executing the lists as QDL later.

        This utility is used in other implementations of processList(InputLine, String)

        Parameters:
        inputLine -
        key -
        Returns: