How to add specific "key" to an ASN1EncodableVector in BouncyCastle? - java

So, I asked a similar question before but the issue has since evolved. So, I'll give you a whole overview and then I'll ask the question.
Currently, I am reading from a .yml file and parsing through it. I then store the data in a HashMap<String, ArrayList > that looks something like this:
[{p_table=[p_event/Name, p_fault/Name]},
{s_table=[s_event/Name, s_fault/Name]},
{r_table=[r_event/Name, r_fault/Name]}]
Now, I understand that if I want to create an extension with bouncycastle I first have to add all of my data into an ASN1EncodableVector. What I'm doing is using certificates to tell my IoT things what topics they can subscribe/publish/receive from. Hence, I can do something like this:
while(iterator.hasNext()) {
Entry<String, ArrayList<String>> entry = iterator.next();
ASN1EncodableVector vector = new ASN1EncodableVector
for(String val : entry.getValue()) {
(vector).add(new DERUTF8String(val));
}
allowedTables.add(new DERSequence(vector));
}
This will only add the values from the arraylist eg p_event/Name or p_fault/Name, is there a way for me to specify that those two DERUTF8String(s) belong to the p_table? Or is there some sort of identifier I can use when using the .add method?
So could the code change from something like this:
(vector).add(new DERUTF8String(val));
to:
(vector).add(new aConstructorToIdentifyWhatTheUTF8BelongsTo(entry.getKey()), new DERUTF8String(val));

You can nest sequences, i.e. you can build one DERSequence for each entry as you are doing and then add each of them to an outer ASN1EncodableVector and make a final sequence from that. The inner sequences could contain key/val/val if the number of values is fixed at 2 as in your example. Or you could have yet another sequence to hold the values e.g.:
SEQUENCE {
SEQUENCE {
"p_table",
SEQUENCE {
"p_event/Name",
"p_fault/Name",
}
},
SEQUENCE {
"s_table",
SEQUENCE {
"s_event/Name",
"s_fault/Name",
"s_other/Name",
}
},
// and so on
}

Related

How can I aggregate elements on a flux by group / how to reduce groupwise?

Assume you have a flux of objects with the following structure:
class Element {
String key;
int count;
}
Now imagine those elements flow in a predefined sort order, always in groups of a key, like
{ key = "firstKey", count=123}
{ key = "firstKey", count=1 }
{ key = "secondKey", count=4 }
{ key = "thirdKey", count=98 }
{ key = "thirdKey", count=5 }
.....
What I want to do is create a flux which returns one element for each distinct key and summed count for each key-group.
So basically like a classic reduce for each group, but using the reduce operator does not work, because it only returns a single element and I want to get a flux with one element for each distinct key.
Using bufferUntil might work, but has the drawback, that I have to keep a state to check if the key has changed in comparison to the previous one.
Using groupBy is an overkill, as I know that each group has come to an end once a new key is found, so I don't want to keep anything cached after that event.
Is such an aggregation possible using Flux, without keeping a state outside of the flow?
This is currently (as of 3.2.5) not possible without keeping track of state yourself. distinctUntilChanged could have fit the bill with minimal state but doesn't emit the state, just the values it considered as "distinct" according to said state.
The most minimalistic way of solving this is with windowUntil and compose + an AtomicReference for state-per-subscriber:
Flux<Tuple2<T, Integer>> sourceFlux = ...; //assuming key/count represented as `Tuple2`
Flux<Tuple2<T, Integer>> aggregated = sourceFlux.compose(source -> {
//having this state inside a compose means it will not be shared by multiple subscribers
AtomicReference<T> last = new AtomicReference<>(null);
return source
//use "last seen" state so split into windows, much like a `groupBy` but with earlier closing
.windowUntil(i -> !i.getT1().equals(last.getAndSet(i.getT1())), true)
//reduce each window
.flatMap(window -> window.reduce((i1, i2) -> Tuples.of(i1.getT1(), i1.getT2() + i2.getT2()))
});
That really worked for me! Thanks for that post.
Please note that in the meantime the "compose" method was renamed. You need to use transformDeferred instead.
In my case I have a "Dashboard" object which has an id (stored as UUID) on which I want to group the source flux:
Flux<Dashboard> sourceFlux = ... // could be a DB query. The Flux must be sorted according the id.
sourceFlux.transformDeferred(dashboardFlux -> {
// this stores the dashboardId's as the Flux publishes. It is used to decide when to open a new window
// having this state inside a compose means it will not be shared by multiple subscribers
AtomicReference<UUID> last = new AtomicReference<>(null);
return dashboardFlux
//use "last seen" state so split into windows, much like a `groupBy` but with earlier closing
.windowUntil(i -> !i.getDashboardId().equals(last.getAndSet(i.getDashboardId())), true)
//reduce each window
.flatMap(window -> window.reduce(... /* reduce one window here */));
})

How to add list of items to an ArrayList<String> in java?

I have list of words which I need to load to ArrayList< String >
prefix.properties
vocab\: = http://myweb.in/myvocab#
hydra\: = http://www.w3.org/ns/hydra/core#
schema\: = http://schema.org/
"vocab:" is actually "vocab:" .Slash(\) is used to read colon(:) character because it is special character.
Dictionary.java
public class Dictionary {
public static ArrayList<String> prefix = new ArrayList<>();
static {
Properties properties = new Properties();
InputStream input = null;
input = ClassLoader.getSystemResourceAsStream("prefix.properties");
System.out.println(input!=null);
try {
properties.load(input);
} catch (IOException e) {
e.printStackTrace();
}
Set<Map.Entry<Object, Object>> entries = properties.entrySet();
for(Map.Entry<Object, Object> E : entries)
{
prefix.add(E.getKey().toString());
prefix.add(E.getValue().toString());
}
}
}
In Dictionary.java , ArrayList prefix will have
prefix = [
"vocab:",
"http://myweb.in/myvocab#",
"hydra:",
"http://www.w3.org/ns/hydra/core#",
"schema:",
"http://schema.org/"
]
I am querying some data in another class.
For eg:
public class QueryClass
{
public ArrayList<String> queryResult(String findKey)
{
ArrayList<String> result = new ArrayList<String>();
ArrayList<String> prefix = Dictionary.prefix;
Iterator<String> iterator = prefix.iterator();
while (iterator.hasNext())
{
String currentKey = iterator.next()+findKey;
/**
Here my logic to search data with this currentKey
*/
}
return result;
}
}
Problem :
I want to avoid this method to load from .properties file because there is possibility of odd number of elements can be present while .properties file provide (key,value) pair way to store data.
Reason why I have to load from separate file ? Because In future I will have to add more keywords/String thats why I put it in prefix.properties file.
Is there any alternative way to do this?
Do not re-invent the wheel.
If you can define the file format, then just go for java properties.
You see, the Properties class has a method getProperty(String, String) where the second argument can be used to pass a default value for example. That method could be used in order to fetch keys that don't come with values.
I would be really careful about inventing your own format; instead I would look into ways of re-using what is already there. Writing code is similar to building roads: people forget that each new road that is built translates to maintenance efforts in the future.
Besides: you add string values to a list of strings by calling list.add(strValue). That is all that is to that.
Edit on your comment: when "java properties" are not what you are looking for; then consider using other formats. For example you could be persisting your data in some JSON based format. And then just go for some existing JSON parser. Actually, your data almost looks like JSON already.
I'm not sure why you need to use ArrayList but if you want to pass these property keys/values, there are 2 better ways:
Use Properties itself.
Convert to HashMap.

Compare data of two or more maps

I am stuck with the below requirement and not sure how can I proceed with it:
I have a function like:
public void compareExcel(Map<Object,List<HashMap>>) compareMaps){}
This function will take a map as an input parameter. This map will contain the sheet name vs Sheet values(Column name - column values) mapping.
Basically the function input parameters will be like:
<Excel1,(scenario:10)
(timing: 20)
Excel2,(scenario:30)
(timing: 40)
Excel3,(scenario:50)
(timing: 60)
>
Here my excel1 having two columns(scenario and timings) and having values as 10 and 20 respectively.
In the result, I will be needing the comparison like:
Map>
<scenario, <excel1,10>
<excel2,30>
<excel3,50>
timing, <excel1,20>
<excel2,40>
<excel3,60>
>
Any help will be appreciated.
Create/initialize the details of you output data-structure
LOOP (over the excelName:List pairs in you input)
LOOP (over the List that is the value in the pair)
//Each entry in the list is a map
Get the key-name (e.g. "scenario")
Get the value (e.g. "10")
//You already know the out key (i.e the excelName)
With the three known values, build/add to your output data-structure
On mobile so I can't even check syntax, but...
Map recopilation = new HashMap();
for(Object sheetName : compareMaps.keySet()) {
Map sheet = compareMaps.get(sheetName);
for (Object columnName : sheet.keySet()) {
if (recopilation.get(columnName) == null) {
recopilation.put(columnName, new HashMap());
}
((Map) recopilation.get(columnName)).put(sheetName, sheet.get(columnName));
}
}
Something like that. If it works, you should really throw some generics in there, I didn't mostly to save some typing.

Check value inside Map

I have a Map where I save values with the form NAME-GROUP.
Before doing some operations, I need to know if the Map contains a specific group,
for example: I need to check for values containing group1 like Mark-group1.
I'm trying to get it this way:
if (checkList.containsValue(group1)) {
exists = true;
}
I can't provide the name when searching because there could be diferent names with the same group.
But it isn't finding the value, as seems that this function just looks for the entire value string and not only for part of it.
So, there would be any way of achieving this, or would I need to change the way I'm focusing my code.
Update--
This is the looking of my Map:
Map<Integer, String> checkList = new HashMap<Integer, String>();
I load some values from a database and I set them into the Map:
if (c.moveToFirst()) {
int checkKey = 0;
do {
checkKey++;
checkList.put(checkKey, c.getString(c.getColumnIndex(TravelOrder.RELATION)));
}while(c.moveToNext());
}
The relation column, has values like: mark-group1, jerry-group1, lewis-group2, etc...
So, the Map will have a structure like [1, mark-group1], etc...
What I need is to check if there is any value inside the map that contains the string group1 for example, I don't care about the name, I just need to know if that group exists there.
If you want to check any value contain your string as a substring you have to do the following:
for (String value : yourMap.values()) {
if (value.contains(subString)) {
return true;
}
}
return false;
By the way if your values in the map are really have two different parts, i suggest to store them in a structure with two fields, so they can be easily searched.

Is there a data structure like the Java Set in JavaScript? [duplicate]

This question already has answers here:
Does JavaScript have an implementation of a set data structure?
(6 answers)
Closed 8 years ago.
I want to use a data structure in JavaScript that can be used to store number of IDs. I should be able to check if a key already exists in that set, something like Java Sets.
I want to achive same behaviours as follows (this code is in Java):
Set<String> st = new HashSet<String>();
//add elemets
if(st.contains("aks") ){
//do something
}
I want a JavaScript/dojo equivalent of the above code.
I've written a JavaScript HashSet implementation that does what you want and allows any object to be a member of the set: http://code.google.com/p/jshashtable
However, if you just need to store strings, you could do something more simply by storing set members as property names of a normal Object. For example:
function StringSet() {
var setObj = {}, val = {};
this.add = function(str) {
setObj[str] = val;
};
this.contains = function(str) {
return setObj[str] === val;
};
this.remove = function(str) {
delete setObj[str];
};
this.values = function() {
var values = [];
for (var i in setObj) {
if (setObj[i] === val) {
values.push(i);
}
}
return values;
};
}
A note about the implementation: val is an object used internally by the StringSet implementation that is unique to each set. Comparing property values of the object whose property names make up the set (setObj) against val eliminates the need for a hasOwnProperty() check and guarantees that only strings that have been added to the set will show up in values.
Example usage:
var set = new StringSet();
set.add("foo");
set.add("bar");
alert(set.contains("foo")); // true
alert(set.contains("baz")); // false
set.values(); // ["foo", "bar"], though not necessarily in that order
set.remove("foo");
set.values(); // ["bar"]
Why not use a normal object and check if a key exists with JavaScript's hasOwnProperty?
var x = {};
x['key'] = 'val';
x.hasOwnProperty('key'); // true //
x.hasOwnProperty('key2'); // false //
And here is a more advanced use case:
var x = {};
var prefix = 'item_';
for(var i=0;i<10;i++){
x[prefix+i] = 'value '+(i+1);
}
x.hasOwnProperty('item_6'); // true //
x.hasOwnProperty('other key'); // false //
Removing items can be done like this:
delete x['key'];
No Dojo needed, this is native to Javascript. Use Objects. Sounds like you only need the keys, not the values. Lookup is constant time.
var st = {'aks':1, 'foo':1, 'bar':1}; // or could start with empty {}. 1 could be any value of any type, it's just short.
//add elements
st.baz = 1;
//or load up dynamically
myArrayOfStrings.forEach(function(key){
st[key] = 1;
});
if("aks" in st){
//do something
}
Possibly with an associative array / Hashtable / dictionary (I don't know how it's called exactly), using the set elements as keys and "anything else" as values.
insert: mySet[key] = "Whatever";
delete: mySet[key] = null;
check: if (mySet[key] != null) { ... }
Hash is good candidate for implementing Set. You could create a set using a function like that:
function set () {
var result = {};
for (var i = 0; i < arguments.length; i++) result[arguments[i]] = true;
return result;
}
For instance:
x = set([1,2,2,4])
x[1] #==> true
x[3] #==> false
x[5] = true; # add element to the set
x[5] = false; # remove element from the set
Sets don't have keys. They only have set of values, but maps have pairs of key/value entities.
As a result, you have 2 options. Each of them has its drawbacks and advantages:
You can use as described above JavaScript object. Actually it is a map/associative array/hash table. One of its advantage - you can guarantee with this kind of structure that keys - are unique items. Its drawback connected to the issue - you have to keep some extra information that you don't need at all. Values of maps. trues or some other values. It does not matter. Why do you need them?
To resolve the previous disadvantage you may consider using JavaScript arrays. But, you'll have to write some wrappers so arrays's behavior will look like sets behavior. Also operations that will search by the uniqueId will be slower than the same ones for hashtables cause you'll have to iterate via all items of an array.
So, I think you should prefer hashtables to arrays, examples you can find in other posts. But probably you should consider changing of your data structure. don't keep uniqueId as keys with unselerss values if its possible. Let your unique ids point to some real objects for which these unique ids are used.
PS: one more thing. Arrays are also objects actually. As a result they can be used as hashtables/maps too.

Categories

Resources