2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 ONAP
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.ccsdk.sli.core.slipluginutils;
 
  23 import java.util.ArrayList;
 
  24 import java.util.HashMap;
 
  25 import java.util.HashSet;
 
  26 import java.util.ListIterator;
 
  29 import org.apache.commons.lang3.StringUtils;
 
  30 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
 
  33  * A utility class used to manage list manipulation in the context memory.
 
  34  * @see org.onap.ccsdk.sli.core.sli.SvcLogicContext
 
  36 public class SvcLogicContextList {
 
  38      * Internal flag indicating if list should be deleted from context memory
 
  39      * when it is copied into the SvcLogicContextList object.
 
  41     private enum OperType {
 
  46     protected final String prefix;
 
  48     protected final ArrayList<HashMap<String,String>> list;
 
  52     public SvcLogicContextList( SvcLogicContext ctx, String list_prefix ) {
 
  53         this(ctx, list_prefix, OperType.COPY);
 
  57     private SvcLogicContextList( SvcLogicContext ctx, String list_prefix, OperType operation ) {
 
  58         this.prefix = list_prefix;
 
  61         int capacity = getCtxListLength(ctx, prefix);
 
  62         this.list = new ArrayList<HashMap<String, String>>(capacity);
 
  63         for( int i = 0; i < capacity; i++ ) {
 
  64             this.list.add(i, new HashMap<String,String>());
 
  67         // Populate "elements" in list
 
  68         String prefix_bracket = this.prefix + '[';
 
  69         for (String key : new HashSet<String>(ctx.getAttributeKeySet())) {
 
  70             if( key.startsWith(prefix_bracket) ) {
 
  71                 // Extract the index of the list
 
  72                 int index = getCtxListIndex(key, this.prefix, capacity);
 
  75                 String suffix = key.substring((prefix_bracket + index + ']').length());
 
  76                 suffix = suffix.isEmpty() ? suffix : suffix.substring(1);
 
  77                 this.list.get(index).put( suffix, ctx.getAttribute(key));
 
  79                 // If flag to extract set, remove data from context memory as
 
  80                 // it is read into this list
 
  81                 if( operation == OperType.EXTRACT ) {
 
  82                     ctx.setAttribute(key, null);
 
  87         // If flag to extract set, remove list _length value from cxt mem
 
  88         if( operation == OperType.EXTRACT ) {
 
  89             ctx.setAttribute(this.prefix + "_length", null);
 
  94     public static SvcLogicContextList extract( SvcLogicContext ctx, String list_prefix ) {
 
  95         return new SvcLogicContextList(ctx, list_prefix, OperType.EXTRACT);
 
  99     // ========== PUBLIC FUNCTIONS ==========
 
 102     public HashMap<String,String> get( int index ) {
 
 103         return this.list.get(index);
 
 107     public HashMap<String,String> remove( int index ) {
 
 108         return this.list.remove(index);
 
 112     public void remove( String value ) {
 
 117     public void remove( String key, String value ) {
 
 118         if( value == null ) {
 
 119             throw new IllegalArgumentException("value cannot be null");
 
 122         ListIterator<HashMap<String,String>> itr = this.list.listIterator();
 
 123         while( itr.hasNext() ) {
 
 124             if( value.equals(itr.next().get(key)) ) {
 
 131     public void remove( Map<String,String> primary_key ) {
 
 132         ListIterator<HashMap<String,String>> itr = this.list.listIterator();
 
 133         while( itr.hasNext() ) {
 
 134             boolean found = true;
 
 135             HashMap<String,String> list_element = itr.next();
 
 136             for( Map.Entry<String,String> key : primary_key.entrySet() ) {
 
 137                 if( !key.getValue().equals(list_element.get(key.getKey())) ) {
 
 155     public void writeToContext( SvcLogicContext ctx ) {
 
 156         ctx.setAttribute( prefix + "_length", Integer.toString(this.list.size()) );
 
 158         for( int i = 0; i < this.list.size(); i++ ) {
 
 159             for( Map.Entry<String,String> entry : this.list.get(i).entrySet() ) {
 
 160                 if( entry.getKey().equals("") ) {
 
 161                     ctx.setAttribute(prefix + '[' + i + ']', entry.getValue());
 
 163                     ctx.setAttribute(prefix + '[' + i + "]." + entry.getKey(), entry.getValue());
 
 171     // ========== PRIVATE STATIC FUNCTIONS ==========
 
 174     private static int getCtxListIndex( String key, String prefix, int list_size ) {
 
 175         int index = getCtxListIndex( key, prefix );
 
 176         if( index >= list_size ) {
 
 177             throw new IllegalArgumentException("Context memory list \"" + prefix + "[]\" contains an index >= the size of the list", new ArrayIndexOutOfBoundsException("index \"" + index + "\" is outside the bounds of the context memory list \"" + prefix + "[]. List Length = " + list_size));
 
 178         } else if (index < 0) {
 
 179             throw new IllegalArgumentException("Context memory list \"" + prefix + "[]\" contains a negative index", new NegativeArraySizeException("index \"" + index + "\" of context memory list is negative"));
 
 186     private static int getCtxListIndex( String key, String prefix ) {
 
 187         String ctx_index_str = StringUtils.substringBetween(key.substring(prefix.length()), "[", "]");
 
 189             return Integer.parseInt( ctx_index_str );
 
 190         } catch (NumberFormatException e) {
 
 191             throw new IllegalStateException("Could not parse index value \"" + ctx_index_str + "\" in context memory key \"" + key + "\"", e);
 
 196     private static int getCtxListLength( SvcLogicContext ctx, String prefix ) {
 
 197         String _length_key = prefix + "_length";
 
 198         String _length_val_str = ctx.getAttribute(_length_key);
 
 200             return Integer.parseInt(_length_val_str);
 
 201         } catch (NumberFormatException e) {
 
 202             if( _length_val_str == null ) {
 
 203                 throw new IllegalStateException( "Could not find list length \"" + _length_key + "\" in context memory." );
 
 205                 throw new IllegalStateException( "Could not parse index value \"" + _length_val_str + "\" of context memory list length \"" + _length_key + "\"" , e );