View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  
21  package org.apache.directory.api.ldap.model.name;
22  
23  
24  import java.time.Duration;
25  
26  import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
27  import org.apache.directory.api.ldap.model.schema.SchemaManager;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  import com.github.benmanes.caffeine.cache.Cache;
32  import com.github.benmanes.caffeine.cache.Caffeine;
33  
34  
35  /**
36   * The default Dn factory implementation.
37   *
38   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
39   */
40  public class DefaultDnFactory implements DnFactory
41  {
42      private static final Logger LOG = LoggerFactory.getLogger( DefaultDnFactory.class );
43  
44      /** The cache for DNs */
45      private Cache<String, Dn> dnCache;
46  
47      /** The schema manager */
48      private SchemaManager schemaManager;
49  
50      /** Flag to enable stats */
51      private boolean enableStats = false;
52  
53      // stat counters
54      private int hitCount = 0;
55      private int missCount = 0;
56  
57  
58      /**
59       * Instantiates a new default Dn factory.
60       *
61       * @param schemaManager The SchemaManager instance
62       * @param cacheSize The cache size used to store DNs
63       */
64      public DefaultDnFactory( SchemaManager schemaManager, int cacheSize )
65      {
66          this.schemaManager = schemaManager;
67          this.dnCache = Caffeine.newBuilder().maximumSize( cacheSize ).expireAfterAccess( Duration.ofMinutes( 10L ) )
68              .build();
69      }
70  
71  
72      /**
73       * {@inheritDoc}
74       */
75      @Override
76      public Dn create( String dn ) throws LdapInvalidDnException
77      {
78          if ( dn == null )
79          {
80              return null;
81          }
82  
83          if ( dn.trim().length() == 0 )
84          {
85              return Dn.ROOT_DSE;
86          }
87  
88          Dn cachedDn = null;
89  
90          // read the explanation at the above DN_CACHE variable declaration
91          // for the reason for performing this check
92          if ( dnCache != null )
93          {
94              cachedDn = dnCache.getIfPresent( dn );
95          }
96  
97          if ( cachedDn == null )
98          {
99              LOG.debug( "Dn {} not found in the cache, creating", dn );
100 
101             cachedDn = new Dn( schemaManager, dn );
102 
103             if ( dnCache != null )
104             {
105                 dnCache.put( dn, cachedDn );
106             }
107 
108             if ( enableStats )
109             {
110                 missCount++;
111             }
112         }
113         else
114         {
115             if ( enableStats )
116             {
117                 hitCount++;
118             }
119         }
120 
121         LOG.debug( "Dn {} found in the cache", dn );
122 
123         if ( enableStats )
124         {
125             LOG.debug( "Dn cache hit - {} , miss - {} and is normalized = {}", hitCount, missCount, cachedDn.isSchemaAware() );
126         }
127 
128         return cachedDn;
129     }
130 
131 
132     /**
133      * {@inheritDoc}
134      */
135     @Override
136     public Dn create( String... upRdns ) throws LdapInvalidDnException
137     {
138         StringBuilder sb = new StringBuilder();
139         boolean isFirst = true;
140         
141         for ( String s : upRdns )
142         {
143             if ( isFirst )
144             {
145                 isFirst = false;
146             }
147             else
148             {
149                 sb.append( ',' );
150             }
151             
152             sb.append( s );
153         }
154 
155         String dn = sb.toString();
156         
157         return create( dn );
158     }
159 
160 }