View Javadoc
1   /*
2    * Tentackle - https://tentackle.org
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17   */
18  
19  package org.tentackle.dbms;
20  
21  import org.tentackle.common.Service;
22  import org.tentackle.session.PersistenceException;
23  import org.tentackle.sql.Backend;
24  
25  import java.util.StringTokenizer;
26  
27  /**
28   * Default {@link IdSourceConfigurator}.
29   * <p>
30   * There are 2 configuration options:
31   * <ol>
32   * <li>table:&lt;name&gt;: an {@link ObjectId} counting in the given table</li>
33   * <li>sequence:&lt;name&gt;[:&lt;sequence-multiplier&gt;:&lt;global-multiplier&gt;]: an {@link ObjectSequenceId}
34   * on the given sequence</li>
35   * </ol>
36   * Without a configuration, the default is {@code sequence:object_sequence_id} if the backend supports
37   * sequences, otherwise {@code table:object_id}.
38   *
39   * @author harald
40   */
41  @Service(IdSourceConfigurator.class)
42  public class DefaultIdSourceConfigurator implements IdSourceConfigurator {
43  
44    /** table-based id source. */
45    public static final String TABLE_BASED = "table";
46  
47    /** sequence-based id source. */
48    public static final String SEQUENCE_BASED = "sequence";
49  
50  
51    /**
52     * Creates an IdSource configurator.
53     */
54    public DefaultIdSourceConfigurator() {
55      // see -Xlint:missing-explicit-ctor since Java 16
56    }
57  
58    @Override
59    public IdSource configure(String idConfig) {
60      // parse
61      String type = null;
62      String name = null;
63      Integer sequenceMultiplier = null;
64      Integer globalMultiplier = null;
65  
66      StringTokenizer stok = new StringTokenizer(idConfig, ":");
67      while (stok.hasMoreTokens()) {
68        String token = stok.nextToken();
69        if (type == null) {
70          type = token;
71        }
72        else if (name == null) {
73          name = token;
74        }
75        else if (sequenceMultiplier == null) {
76          sequenceMultiplier = Integer.parseInt(token);
77        }
78        else if (globalMultiplier == null) {
79          globalMultiplier = Integer.parseInt(token);
80        }
81        else {
82          throw new PersistenceException("malformed idSource configuration: " + idConfig);
83        }
84      }
85  
86      if (type == null) {
87        throw new PersistenceException("empty id configuration");
88      }
89  
90      return switch (type) {
91        case SEQUENCE_BASED -> {
92          if (sequenceMultiplier == null) {   // implies globalMultiplier == null
93            yield ObjectSequenceId.get(name);
94          }
95          else if (globalMultiplier != null) {
96            yield ObjectSequenceId.get(name, sequenceMultiplier, globalMultiplier);
97          }
98          throw new PersistenceException("sequenceMultiplier and globalMultiplier must be defined both or not at all");
99        }
100       case TABLE_BASED -> ObjectId.get(name);
101       default -> throw new PersistenceException("unsupported idSource type: " + type);
102     };
103   }
104 
105   @Override
106   public IdSource configure(Backend backend) {
107     if (backend.isSequenceSupported()) {
108       return configure(SEQUENCE_BASED + ":object_sequence_id");
109     }
110     else  {
111       return configure(TABLE_BASED + ":object_id");
112     }
113   }
114 
115 }