89a4a98ffe31f8c0729024d633fcb23d7cf12369
[ccsdk/sli/core.git] / sliPluginUtils / provider / src / main / java / org / openecomp / sdnc / sli / SliPluginUtils / SvcLogicContextList.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.sdnc.sli.SliPluginUtils;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.ListIterator;
28 import java.util.Map;
29
30 import org.apache.commons.lang3.StringUtils;
31 import org.openecomp.sdnc.sli.SvcLogicContext;
32
33 /**
34  * A utility class used to manage list manipulation in the context memory.
35  * @see org.openecomp.sdnc.sli.SvcLogicContext
36  */
37 public class SvcLogicContextList {
38     /**
39      * Internal flag indicating if list should be deleted from context memory
40      * when it is copied into the SvcLogicContextList object.
41      */
42     private enum OperType {
43         COPY, EXTRACT
44     }
45
46     // TODO: javadoc
47     protected final String prefix;
48     // TODO: javadoc
49     protected final ArrayList<HashMap<String,String>> list;
50
51
52     // TODO: javadoc
53     public SvcLogicContextList( SvcLogicContext ctx, String list_prefix ) {
54         this(ctx, list_prefix, OperType.COPY);
55     }
56
57     // TODO: javadoc
58     private SvcLogicContextList( SvcLogicContext ctx, String list_prefix, OperType operation ) {
59         this.prefix = list_prefix;
60
61         // Initialize list
62         int capacity = getCtxListLength(ctx, prefix);
63         this.list = new ArrayList<HashMap<String, String>>(capacity);
64         for( int i = 0; i < capacity; i++ ) {
65             this.list.add(i, new HashMap<String,String>());
66         }
67
68         // Populate "elements" in list
69         String prefix_bracket = this.prefix + '[';
70         for (String key : new HashSet<String>(ctx.getAttributeKeySet())) {
71             if( key.startsWith(prefix_bracket) ) {
72                 // Extract the index of the list
73                 int index = getCtxListIndex(key, this.prefix, capacity);
74
75                 // Store the
76                 String suffix = key.substring((prefix_bracket + index + ']').length());
77                 suffix = suffix.isEmpty() ? suffix : suffix.substring(1);
78                 this.list.get(index).put( suffix, ctx.getAttribute(key));
79
80                 // If flag to extract set, remove data from context memory as
81                 // it is read into this list
82                 if( operation == OperType.EXTRACT ) {
83                     ctx.setAttribute(key, null);
84                 }
85             }
86         }
87
88         // If flag to extract set, remove list _length value from cxt mem
89         if( operation == OperType.EXTRACT ) {
90             ctx.setAttribute(this.prefix + "_length", null);
91         }
92     }
93
94     // TODO: javadoc
95     public static SvcLogicContextList extract( SvcLogicContext ctx, String list_prefix ) {
96         return new SvcLogicContextList(ctx, list_prefix, OperType.EXTRACT);
97     }
98
99
100     // ========== PUBLIC FUNCTIONS ==========
101
102     // TODO: javadoc
103     public HashMap<String,String> get( int index ) {
104         return this.list.get(index);
105     }
106
107     // TODO: javadoc
108     public HashMap<String,String> remove( int index ) {
109         return this.list.remove(index);
110     }
111
112     // TODO: javadoc
113     public void remove( String value ) {
114         remove( "", value );
115     }
116
117     // TODO: javadoc
118     public void remove( String key, String value ) {
119         if( value == null ) {
120             throw new IllegalArgumentException("value cannot be null");
121         }
122
123         ListIterator<HashMap<String,String>> itr = this.list.listIterator();
124         while( itr.hasNext() ) {
125             if( value.equals(itr.next().get(key)) ) {
126                 itr.remove();
127             }
128         }
129     }
130
131     // TODO javadoc
132     public void remove( Map<String,String> primary_key ) {
133         ListIterator<HashMap<String,String>> itr = this.list.listIterator();
134         while( itr.hasNext() ) {
135             boolean found = true;
136             HashMap<String,String> list_element = itr.next();
137             for( Map.Entry<String,String> key : primary_key.entrySet() ) {
138                 if( !key.getValue().equals(list_element.get(key.getKey())) ) {
139                     found = false;
140                     break;
141                 }
142             }
143
144             if( found ) {
145                 itr.remove();
146             }
147         }
148     }
149
150     // TODO: javadoc
151     public int size() {
152         return list.size();
153     }
154
155     // TODO: javadoc
156     public void writeToContext( SvcLogicContext ctx ) {
157         ctx.setAttribute( prefix + "_length", Integer.toString(this.list.size()) );
158
159         for( int i = 0; i < this.list.size(); i++ ) {
160             for( Map.Entry<String,String> entry : this.list.get(i).entrySet() ) {
161                 if( entry.getKey().equals("") ) {
162                     ctx.setAttribute(prefix + '[' + i + ']', entry.getValue());
163                 } else {
164                     ctx.setAttribute(prefix + '[' + i + "]." + entry.getKey(), entry.getValue());
165                 }
166             }
167         }
168     }
169
170
171
172     // ========== PRIVATE STATIC FUNCTIONS ==========
173
174     // TODO: javadoc
175     private static int getCtxListIndex( String key, String prefix, int list_size ) {
176         int index = getCtxListIndex( key, prefix );
177         if( index >= list_size ) {
178             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));
179         } else if (index < 0) {
180             throw new IllegalArgumentException("Context memory list \"" + prefix + "[]\" contains a negative index", new NegativeArraySizeException("index \"" + index + "\" of context memory list is negative"));
181         }
182
183         return index;
184     }
185
186     // TODO: javadoc
187     private static int getCtxListIndex( String key, String prefix ) {
188         String ctx_index_str = StringUtils.substringBetween(key.substring(prefix.length()), "[", "]");
189         try {
190             return Integer.parseInt( ctx_index_str );
191         } catch (NumberFormatException e) {
192             throw new IllegalStateException("Could not parse index value \"" + ctx_index_str + "\" in context memory key \"" + key + "\"", e);
193         }
194     }
195
196     // TODO: javadoc
197     private static int getCtxListLength( SvcLogicContext ctx, String prefix ) {
198         String _length_key = prefix + "_length";
199         String _length_val_str = ctx.getAttribute(_length_key);
200         try {
201             return Integer.parseInt(_length_val_str);
202         } catch (NumberFormatException e) {
203             if( _length_val_str == null ) {
204                 throw new IllegalStateException( "Could not find list length \"" + _length_key + "\" in context memory." );
205             } else {
206                 throw new IllegalStateException( "Could not parse index value \"" + _length_val_str + "\" of context memory list length \"" + _length_key + "\"" , e );
207             }
208         }
209     }
210 }