LightJason - AgentSpeak(L++)
CViewMap.java
Go to the documentation of this file.
1 /*
2  * @cond LICENSE
3  * ######################################################################################
4  * # LGPL License #
5  * # #
6  * # This file is part of the LightJason AgentSpeak(L++) #
7  * # Copyright (c) 2015-19, LightJason (info@lightjason.org) #
8  * # This program is free software: you can redistribute it and/or modify #
9  * # it under the terms of the GNU Lesser General Public License as #
10  * # published by the Free Software Foundation, either version 3 of the #
11  * # License, or (at your option) any later version. #
12  * # #
13  * # This program is distributed in the hope that it will be useful, #
14  * # but WITHOUT ANY WARRANTY; without even the implied warranty of #
15  * # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
16  * # GNU Lesser General Public License for more details. #
17  * # #
18  * # You should have received a copy of the GNU Lesser General Public License #
19  * # along with this program. If not, see http://www.gnu.org/licenses/ #
20  * ######################################################################################
21  * @endcond
22  */
23 
24 package org.lightjason.agentspeak.beliefbase.view;
25 
26 import org.apache.commons.lang3.tuple.ImmutablePair;
27 import org.apache.commons.lang3.tuple.Pair;
37 
38 import javax.annotation.Nonnull;
39 import javax.annotation.Nullable;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.Locale;
44 import java.util.Map;
45 import java.util.Objects;
46 import java.util.concurrent.ConcurrentHashMap;
47 import java.util.function.BiConsumer;
48 import java.util.function.Consumer;
49 import java.util.function.Function;
50 import java.util.stream.Collectors;
51 import java.util.stream.Stream;
52 
53 
60 public final class CViewMap implements IView
61 {
65  private final String m_name;
69  private final IView m_parent;
77  private final Map<String, Object> m_data;
81  private final Function<String, String> m_literaltokey;
85  private final Function<String, String> m_keytoliteral;
89  private final Consumer<Map<String, Object>> m_clearconsumer;
93  private final BiConsumer<String, Map<String, Object>> m_addviewconsumer;
97  private final BiConsumer<Pair<String, Stream<ITerm>>, Map<String, Object>> m_addliteralconsumer;
101  private final BiConsumer<String, Map<String, Object>> m_removeviewconsumer;
105  private final BiConsumer<String, Map<String, Object>> m_removeliteralconsumer;
106 
113  public CViewMap( @Nonnull final String p_name, @Nonnull final Map<String, Object> p_map )
114  {
115  this( p_name, p_map, null );
116  }
117 
125  public CViewMap( @Nonnull final String p_name, @Nonnull final Map<String, Object> p_map, @Nullable final IView p_parent )
126  {
127  this(
128  p_name, p_map, p_parent,
129  // add view
130  ( i, j ) -> j.putIfAbsent( i, new ConcurrentHashMap<>() ),
131  // add literal
132  ( i, j ) -> i.getValue().limit( 1 ).filter( ITerm::raw ).forEach( n -> j.put( i.getKey(), n.raw() ) ),
133  // remove view
134  ( i, j ) ->
135  {
136  final Object l_data = j.get( i );
137  if ( l_data instanceof Map<?, ?> )
138  j.remove( i, l_data );
139  },
140  // remove literal
141  ( i, j ) ->
142  {
143  final Object l_data = j.get( i );
144  if ( !( l_data instanceof Map<?, ?> ) )
145  j.remove( i, l_data );
146  },
147  Map::clear,
148  i -> i.toLowerCase( Locale.ROOT ),
149  i -> i.toLowerCase( Locale.ROOT )
150  );
151  }
152 
167  public CViewMap( @Nonnull final String p_name, @Nonnull final Map<String, Object> p_map, @Nullable final IView p_parent,
168  @Nonnull final BiConsumer<String, Map<String, Object>> p_addviewconsumer,
169  @Nonnull final BiConsumer<Pair<String, Stream<ITerm>>, Map<String, Object>> p_addliteralconsumer,
170  @Nonnull final BiConsumer<String, Map<String, Object>> p_removeviewconsumer,
171  @Nonnull final BiConsumer<String, Map<String, Object>> p_removeliteralconsumer,
172  @Nonnull final Consumer<Map<String, Object>> p_clearconsumer,
173  @Nonnull final Function<String, String> p_literaltokey, @Nonnull final Function<String, String> p_keytoliteral
174  )
175  {
176  m_name = p_name;
177  m_parent = p_parent;
178  m_data = p_map;
179  m_literaltokey = p_literaltokey;
180  m_keytoliteral = p_keytoliteral;
181  m_clearconsumer = p_clearconsumer;
182  m_addviewconsumer = p_addviewconsumer;
183  m_addliteralconsumer = p_addliteralconsumer;
184  m_removeviewconsumer = p_removeviewconsumer;
185  m_removeliteralconsumer = p_removeliteralconsumer;
186  }
187 
188  @Nonnull
189  @Override
190  public final Stream<IView> walk( @Nonnull final IPath p_path, @Nullable final IViewGenerator... p_generator )
191  {
192  return this.walkdown( p_path, p_generator );
193  }
194 
195  @Nonnull
196  @Override
197  public IView generate( @Nonnull final IViewGenerator p_generator, @Nonnull final IPath... p_paths )
198  {
199  return this;
200  }
201 
202  @Nonnull
203  @Override
204  public final Stream<IView> root()
205  {
206  return this.hasParent()
207  ? Stream.concat( Stream.of( this ), Stream.of( this.parent() ).flatMap( IView::root ) )
208  : Stream.empty();
209  }
210 
211  @Nonnull
212  @Override
213  public final IBeliefbase beliefbase()
214  {
215  return m_beliefbase;
216  }
217 
218  @Nonnull
219  @Override
220  public final IPath path()
221  {
222  return this.root().map( IView::name ).collect( CPath.collect() ).reverse();
223  }
224 
225  @Nonnull
226  @Override
227  public final String name()
228  {
229  return m_name;
230  }
231 
232  @Nullable
233  @Override
234  public final IView parent()
235  {
236  return m_parent;
237  }
238 
239  @Override
240  public final boolean hasParent()
241  {
242  return m_parent != null;
243  }
244 
245  @Nonnull
246  @Override
247  public final Stream<ITrigger> trigger()
248  {
249  return m_beliefbase.trigger( this );
250  }
251 
252  @Nonnull
253  @Override
254  @SuppressWarnings( "unchecked" )
255  public final Stream<ILiteral> stream( @Nullable final IPath... p_path )
256  {
257  // build path relative to this view
258  final IPath l_path = this.path();
259  return ( ( Objects.isNull( p_path ) ) || ( p_path.length == 0 )
260  ? Stream.concat( m_beliefbase.streamLiteral(), m_beliefbase.streamView().flatMap( i -> i.stream() ) )
261  : Arrays.stream( p_path )
262  .flatMap( i -> this.leafview( this.walk( i.subpath( 0, -1 ) ) ).beliefbase().literal( i.suffix() ).stream() )
263  ).map( i -> i.shallowcopy( l_path ) );
264  }
265 
266  @Nonnull
267  @Override
268  public final Stream<ILiteral> stream( final boolean p_negated, @Nullable final IPath... p_path )
269  {
270  return p_negated ? Stream.empty() : this.stream( p_path );
271  }
272 
273  @Nonnull
274  @Override
275  public final IView clear( @Nullable final IPath... p_path )
276  {
277  if ( ( Objects.isNull( p_path ) ) || ( p_path.length == 0 ) )
278  m_clearconsumer.accept( m_data );
279  else
280  Arrays.stream( p_path ).flatMap( i -> this.walkdown( i ) ).forEach( i -> i.clear() );
281 
282  return this;
283  }
284 
285  @Nonnull
286  @Override
287  public final IView add( @Nonnull final Stream<ILiteral> p_literal )
288  {
289  p_literal.forEach( m_beliefbase::add );
290  return this;
291  }
292 
293  @Nonnull
294  @Override
295  public final IView add( @Nonnull final ILiteral... p_literal )
296  {
297  return this.add( Arrays.stream( p_literal ) );
298  }
299 
300  @Nonnull
301  @Override
302  @SuppressWarnings( "varargs" )
303  public final IView add( @Nonnull final IView... p_view )
304  {
305  Arrays.stream( p_view ).forEach( m_beliefbase::remove );
306  return this;
307  }
308 
309  @Nonnull
310  @Override
311  public IView remove( @Nonnull final Stream<ILiteral> p_literal )
312  {
313  p_literal.forEach( m_beliefbase::remove );
314  return this;
315  }
316 
317  @Nonnull
318  @Override
319  @SuppressWarnings( "varargs" )
320  public IView remove( @Nonnull final ILiteral... p_literal )
321  {
322  return this.remove( Arrays.stream( p_literal ) );
323  }
324 
325  @Nonnull
326  @Override
327  @SuppressWarnings( "varargs" )
328  public final IView remove( @Nonnull final IView... p_view )
329  {
330  Arrays.stream( p_view ).forEach( m_beliefbase::remove );
331  return this;
332  }
333 
334  @Override
335  @SuppressWarnings( "unchecked" )
336  public boolean containsLiteral( @Nonnull final IPath p_path )
337  {
338  return !p_path.empty()
339  && ( p_path.size() == 1
340  ? m_beliefbase.containsLiteral( p_path.get( 0 ) )
341  : this.leafview( this.walk( p_path.subpath( 0, p_path.size() - 1 ) ) )
342  .containsLiteral( p_path.subpath( p_path.size() - 1, p_path.size() ) )
343  );
344  }
345 
346  @Override
347  @SuppressWarnings( "unchecked" )
348  public final boolean containsView( @Nonnull final IPath p_path )
349  {
350  return !p_path.empty()
351  && ( p_path.size() == 1
352  ? m_beliefbase.containsView( p_path.get( 0 ) )
353  : this.leafview( this.walk( p_path.subpath( 0, p_path.size() - 1 ) ) )
354  .containsView( p_path.subpath( p_path.size() - 1, p_path.size() ) )
355  );
356  }
357 
358  @Override
359  public final boolean empty()
360  {
361  return m_beliefbase.empty();
362  }
363 
364  @Override
365  public final int size()
366  {
367  return m_beliefbase.size();
368  }
369 
370  @Nonnull
371  @Override
372  public final IAgent<?> update( @Nonnull final IAgent<?> p_agent )
373  {
374  return m_beliefbase.update( p_agent );
375  }
376 
383  @Nonnull
384  private IView leafview( @Nonnull final Stream<IView> p_stream )
385  {
386  return p_stream
387  .reduce( ( i, j ) -> j )
388  .orElse( this );
389  }
390 
391  @SuppressWarnings( "unchecked" )
392  private Stream<IView> walkdown( final IPath p_path, @Nullable final IViewGenerator... p_generator )
393  {
394  if ( p_path.empty() )
395  return Stream.of( this );
396 
397  final String l_key = m_literaltokey.apply( p_path.get( 0 ) );
398  final Object l_data = m_data.get( l_key );
399  return l_data instanceof Map<?, ?>
400  ? Stream.concat(
401  Stream.of( this ),
402  new CViewMap(
403  l_key, (Map<String, Object>) l_data, this,
405  ).walk( p_path.subpath( 1 ), p_generator ) )
406  : Stream.of( this );
407  }
408 
409 
413  private final class CWrapperBeliefbase implements IBeliefbase
414  {
415 
416  @Override
417  public final boolean empty()
418  {
419  return m_data.isEmpty();
420  }
421 
422  @Override
423  @SuppressWarnings( "unchecked" )
424  public final int size()
425  {
426  return (int) m_data.values()
427  .stream()
428  .filter( i -> !( i instanceof Map<?, ?> ) )
429  .count()
430  + m_data.entrySet()
431  .stream()
432  .filter( i -> i instanceof Map<?, ?> )
433  .mapToInt( i -> new CViewMap( i.getKey(), (Map<String, Object>) i.getValue() ).size() )
434  .sum();
435  }
436 
437  @Nonnull
438  @Override
439  public final IAgent<?> update( @Nonnull final IAgent<?> p_agent )
440  {
441  return p_agent;
442  }
443 
444  @Nonnull
445  @Override
446  public final Stream<ITrigger> trigger( @Nonnull final IView p_view )
447  {
448  return Stream.empty();
449  }
450 
451  @Nonnull
452  @Override
453  @SuppressWarnings( "unchecked" )
454  public final Stream<ILiteral> streamLiteral()
455  {
456  return m_data.entrySet()
457  .stream()
458  .filter( i -> !( i.getValue() instanceof Map<?, ?> ) )
459  .map( i -> CLiteral.from( m_keytoliteral.apply( i.getKey() ), this.toterm( i.getValue() ) ) );
460  }
461 
462  @Nonnull
463  @Override
464  @SuppressWarnings( "unchecked" )
465  public final Stream<IView> streamView()
466  {
467  return m_data.entrySet()
468  .stream()
469  .filter( i -> i.getValue() instanceof Map<?, ?> )
470  .map( i -> new CViewMap( m_keytoliteral.apply( i.getKey() ), (Map<String, Object>) i.getValue() ) );
471  }
472 
473  @Nonnull
474  @Override
475  public final IBeliefbase clear()
476  {
477  m_data.clear();
478  return this;
479  }
480 
481  @Nonnull
482  @Override
483  public final ILiteral add( @Nonnull final ILiteral p_literal )
484  {
485  m_addliteralconsumer.accept( new ImmutablePair<>( m_literaltokey.apply( p_literal.functor() ), p_literal.orderedvalues() ), m_data );
486  return p_literal;
487  }
488 
489  @Nonnull
490  @Override
491  public final IView add( @Nonnull final IView p_view )
492  {
493  m_addviewconsumer.accept( m_keytoliteral.apply( p_view.name() ), m_data );
494  return p_view;
495  }
496 
497  @Nonnull
498  @Override
499  public final ILiteral remove( @Nonnull final ILiteral p_literal )
500  {
501  m_removeliteralconsumer.accept( m_literaltokey.apply( p_literal.functor() ), m_data );
502  return p_literal;
503  }
504 
505  @Nonnull
506  @Override
507  public final IView remove( @Nonnull final IView p_view )
508  {
509  m_removeviewconsumer.accept( m_literaltokey.apply( p_view.name() ), m_data );
510  return p_view;
511  }
512 
513  @Override
514  public final boolean containsLiteral( @Nonnull final String p_key )
515  {
516  final String l_key = m_literaltokey.apply( p_key );
517  return m_data.containsKey( l_key ) && ( !( m_data.get( l_key ) instanceof Map<?, ?> ) );
518  }
519 
520  @Override
521  public boolean containsView( @Nonnull final String p_key )
522  {
523  final String l_key = m_literaltokey.apply( p_key );
524  return m_data.containsKey( l_key ) && ( m_data.get( l_key ) instanceof Map<?, ?> );
525  }
526 
527  @Nullable
528  @Override
529  public final IView view( @Nonnull final String p_key )
530  {
531  return CViewMap.this;
532  }
533 
534  @Nonnull
535  @Override
536  public final Collection<ILiteral> literal( @Nonnull final String p_key )
537  {
538  final String l_key = m_literaltokey.apply( p_key );
539  if ( !m_data.containsKey( l_key ) )
540  return Collections.emptySet();
541 
542  final Object l_data = m_data.get( l_key );
543  if ( m_data.get( l_key ) instanceof Map<?, ?> )
544  return Collections.emptySet();
545 
546  return Stream.of( CLiteral.from( p_key, this.toterm( l_data ) ) ).collect( Collectors.toSet() );
547  }
548 
549  @Nullable
550  @Override
551  public final IView viewOrDefault( @Nonnull final String p_key, @Nullable final IView p_default )
552  {
553  return null;
554  }
555 
556  @Nonnull
557  @Override
558  public final IView create( @Nonnull final String p_name )
559  {
560  return CViewMap.this;
561  }
562 
563  @Nonnull
564  @Override
565  public final IView create( @Nonnull final String p_name, @Nullable final IView p_parent )
566  {
567  return CViewMap.this;
568  }
569 
570  @SuppressWarnings( "unchecked" )
571  private Stream<ITerm> toterm( final Object p_value )
572  {
573  if ( p_value instanceof Collection<?> )
574  return ( (Collection<Object>) p_value ).stream().flatMap( this::toterm );
575 
576  if ( p_value instanceof Map<?, ?> )
577  return ( (Map<String, Object>) p_value ).entrySet().stream()
578  .map( i -> CLiteral.from( m_keytoliteral.apply( i.getKey() ), this.toterm( i.getValue() ) ) );
579 
580  if ( p_value instanceof Integer )
581  return Stream.of( CRawTerm.from( ( (Number) p_value ).longValue() ) );
582 
583  return Stream.of( CRawTerm.from( p_value ) );
584  }
585  }
586 }
final IView create( @Nonnull final String p_name)
returns a new view of the belief base
Definition: CViewMap.java:558
Stream< IView > streamView()
returns a stream over all views
CViewMap( @Nonnull final String p_name, @Nonnull final Map< String, Object > p_map)
ctor
Definition: CViewMap.java:113
final BiConsumer< Pair< String, Stream< ITerm > >, Map< String, Object > > m_addliteralconsumer
add-literal consumer
Definition: CViewMap.java:97
final Function< String, String > m_keytoliteral
key to literal converting
Definition: CViewMap.java:85
final int size()
returns the size of literals
Definition: CViewMap.java:365
CViewMap( @Nonnull final String p_name, @Nonnull final Map< String, Object > p_map, @Nullable final IView p_parent, @Nonnull final BiConsumer< String, Map< String, Object >> p_addviewconsumer, @Nonnull final BiConsumer< Pair< String, Stream< ITerm >>, Map< String, Object >> p_addliteralconsumer, @Nonnull final BiConsumer< String, Map< String, Object >> p_removeviewconsumer, @Nonnull final BiConsumer< String, Map< String, Object >> p_removeliteralconsumer, @Nonnull final Consumer< Map< String, Object >> p_clearconsumer, @Nonnull final Function< String, String > p_literaltokey, @Nonnull final Function< String, String > p_keytoliteral)
ctor
Definition: CViewMap.java:167
final IView view( @Nonnull final String p_key)
returns a view element
Definition: CViewMap.java:529
final Stream< ITrigger > trigger()
retruns all trigger of the beliefbase
Definition: CViewMap.java:247
boolean containsView( @Nonnull final String p_key)
contains a single-element
Definition: CViewMap.java:521
IAgent<?> update( @Nonnull final IAgent<?> p_agent)
updates all items
final IView parent()
returns the parent of the view
Definition: CViewMap.java:234
IView leafview( @Nonnull final Stream< IView > p_stream)
returns the leaf of a view path
Definition: CViewMap.java:384
final IView create( @Nonnull final String p_name, @Nullable final IView p_parent)
returns a new view of the belief base
Definition: CViewMap.java:565
final IView add( @Nonnull final Stream< ILiteral > p_literal)
adds a literal in the current structure
Definition: CViewMap.java:287
Stream< ILiteral > stream( @Nullable final IPath... p_path)
returns stream of literal
class to create a path structure
Definition: CPath.java:53
final boolean empty()
checks if the structure empty
Definition: CViewMap.java:417
final IAgent<?> update( @Nonnull final IAgent<?> p_agent)
updates all items
Definition: CViewMap.java:372
IView generate( @Nonnull final IViewGenerator p_generator, @Nonnull final IPath... p_paths)
generates path structure
Definition: CViewMap.java:197
final Stream< ITrigger > trigger( @Nonnull final IView p_view)
returns all trigger of the beliefbase
Definition: CViewMap.java:446
boolean empty()
checks if the structure empty
final IView clear( @Nullable final IPath... p_path)
clears all elements
Definition: CViewMap.java:275
IBeliefbase beliefbase()
returns the beliefbase
view for a beliefbase that creates any access to the underlying data structures
Definition: IView.java:44
final IBeliefbase beliefbase()
returns the beliefbase
Definition: CViewMap.java:213
Stream< ITrigger > trigger( @Nonnull final IView p_view)
returns all trigger of the beliefbase
boolean containsLiteral( @Nonnull final String p_key)
contains a multi-element
final String name()
returns only the element name
Definition: CViewMap.java:227
final boolean hasParent()
check if the view has got a parent
Definition: CViewMap.java:240
final Stream< IView > root()
returns a stream to the root node,
Definition: CViewMap.java:204
final Stream< IView > streamView()
returns a stream over all views
Definition: CViewMap.java:465
final BiConsumer< String, Map< String, Object > > m_addviewconsumer
add-view consumer
Definition: CViewMap.java:93
interface of beliefbase definition, that create the trigger events for the agent
String name()
returns only the element name
final IView viewOrDefault( @Nonnull final String p_key, @Nullable final IView p_default)
returns a view element
Definition: CViewMap.java:551
final Map< String, Object > m_data
root map
Definition: CViewMap.java:77
final ILiteral add( @Nonnull final ILiteral p_literal)
adds a literal
Definition: CViewMap.java:483
final Stream< ILiteral > streamLiteral()
returns a stream over all literals
Definition: CViewMap.java:454
final Collection< ILiteral > literal( @Nonnull final String p_key)
returns a literal by the name
Definition: CViewMap.java:536
final IPath path()
returns the full path
Definition: CViewMap.java:220
final BiConsumer< String, Map< String, Object > > m_removeliteralconsumer
remove-literal consumer
Definition: CViewMap.java:105
IView remove( @Nonnull final Stream< ILiteral > p_literal)
removes a literal in the current structure
Definition: CViewMap.java:311
default generic literal class for agent beliefs a literal consists of a functor, an optional list of ...
Definition: CLiteral.java:64
Stream< IView > root()
returns a stream to the root node,
final boolean containsLiteral( @Nonnull final String p_key)
contains a multi-element
Definition: CViewMap.java:514
< T > T raw()
cast to any raw value type
Collection< ILiteral > literal( @Nonnull final String p_key)
returns a literal by the name
interface for generating non-existing beliefbases views
final Stream< IView > walk( @Nonnull final IPath p_path, @Nullable final IViewGenerator... p_generator)
streams path walking
Definition: CViewMap.java:190
static< N > CRawTerm< N > from(final N p_value)
factory for a raw term
Definition: CRawTerm.java:104
final BiConsumer< String, Map< String, Object > > m_removeviewconsumer
remove-view consumer
Definition: CViewMap.java:101
final boolean empty()
checks if the structure empty
Definition: CViewMap.java:359
Stream< ILiteral > streamLiteral()
returns a stream over all literals
final boolean containsView( @Nonnull final IPath p_path)
view existing check
Definition: CViewMap.java:348
final Stream< ILiteral > stream( @Nullable final IPath... p_path)
returns stream of literal
Definition: CViewMap.java:255
static ILiteral from( @Nonnull final String p_functor, @Nullable final ITerm... p_values)
factory
Definition: CLiteral.java:161
int size()
returns the size of literals
final IView add( @Nonnull final IView p_view)
adds a view
Definition: CViewMap.java:491
final IAgent<?> update( @Nonnull final IAgent<?> p_agent)
updates all items
Definition: CViewMap.java:439
view which can use a map of maps to represent the hierarchical beliefbase structure ...
Definition: CViewMap.java:60
final IView add( @Nonnull final ILiteral... p_literal)
adds a literal in the current structure
Definition: CViewMap.java:295
CViewMap( @Nonnull final String p_name, @Nonnull final Map< String, Object > p_map, @Nullable final IView p_parent)
ctor
Definition: CViewMap.java:125
boolean containsView( @Nonnull final String p_key)
contains a single-element
final IBeliefbase m_beliefbase
beliefbase
Definition: CViewMap.java:73
static Collector< String, IPath, IPath > collect()
returns a collector to build a path from strings
Definition: CPath.java:506
final Consumer< Map< String, Object > > m_clearconsumer
clear consumer
Definition: CViewMap.java:89
Stream< IView > walkdown(final IPath p_path, @Nullable final IViewGenerator... p_generator)
Definition: CViewMap.java:392
final Function< String, String > m_literaltokey
path to key converting
Definition: CViewMap.java:81
final Stream< ILiteral > stream(final boolean p_negated, @Nullable final IPath... p_path)
returns stream of literal
Definition: CViewMap.java:268
boolean containsLiteral( @Nonnull final IPath p_path)
checks if a literal exists
Definition: CViewMap.java:336
term structure for simple datatypes
Definition: CRawTerm.java:45