001 /*
002 * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org
003 * Copyright (C) 2011 NightLabs Consulting GmbH
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
017 */
018 package org.cumulus4j.store.model;
019
020 import javax.jdo.JDOObjectNotFoundException;
021 import javax.jdo.PersistenceManager;
022 import javax.jdo.annotations.Column;
023 import javax.jdo.annotations.IdentityType;
024 import javax.jdo.annotations.NullValue;
025 import javax.jdo.annotations.PersistenceCapable;
026 import javax.jdo.annotations.Persistent;
027 import javax.jdo.annotations.PrimaryKey;
028 import javax.jdo.identity.StringIdentity;
029
030 import org.cumulus4j.store.Cumulus4jIncrementGenerator;
031
032 /**
033 * Persistent sequence entity used by {@link Cumulus4jIncrementGenerator}.
034 *
035 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
036 */
037 @PersistenceCapable(identityType=IdentityType.APPLICATION, detachable="true")
038 public class Sequence
039 {
040 /**
041 * Get the <code>Sequence</code> identified by the given <code>sequenceName</code>.
042 * If no such <code>Sequence</code> exists, this method returns <code>null</code>.
043 * @param pm the backend-<code>PersistenceManager</code> used to access the underlying datastore; must not be <code>null</code>.
044 * @param sequenceName the name of the sequence; must not be <code>null</code>.
045 * @return the <code>Sequence</code> identified by the given <code>sequenceName</code> or <code>null</code>, if no such
046 * <code>Sequence</code> exists.
047 */
048 public static Sequence getSequence(PersistenceManager pm, String sequenceName)
049 {
050 StringIdentity id = new StringIdentity(Sequence.class, sequenceName);
051 Sequence sequence;
052 try {
053 sequence = (Sequence) pm.getObjectById(id);
054 } catch (JDOObjectNotFoundException x) {
055 sequence = null;
056 }
057 return sequence;
058 }
059
060 /**
061 * Get the <code>Sequence</code> identified by the given <code>sequenceName</code>.
062 * If no such <code>Sequence</code> exists, this method creates & persists one.
063 * @param pm the backend-<code>PersistenceManager</code> used to access the underlying datastore; must not be <code>null</code>.
064 * @param sequenceName the name of the sequence; must not be <code>null</code>.
065 * @return the <code>Sequence</code> identified by the given <code>sequenceName</code>; never <code>null</code>.
066 */
067 public static Sequence createSequence(PersistenceManager pm, String sequenceName)
068 {
069 Sequence sequence = getSequence(pm, sequenceName);
070 if (sequence == null)
071 sequence = pm.makePersistent(new Sequence(sequenceName));
072
073 return sequence;
074 }
075
076 @PrimaryKey
077 @Persistent(nullValue=NullValue.EXCEPTION)
078 @Column(length=255)
079 private String sequenceName;
080
081 private long nextValue = 1;
082
083 /**
084 * Default constructor. Should never be used by actual code! It exists only to fulfill the JDO requirements.
085 */
086 protected Sequence() { }
087
088 /**
089 * Constructor creating a <code>Sequence</code> with the given primary key.
090 * @param sequenceName the name of the sequence; must not be <code>null</code>.
091 */
092 protected Sequence(String sequenceName)
093 {
094 if (sequenceName == null)
095 throw new IllegalArgumentException("sequenceName == null");
096
097 this.sequenceName = sequenceName;
098 }
099
100 /**
101 * Get the name of the sequence.
102 * @return the name of the sequence.
103 */
104 public String getSequenceName() {
105 return sequenceName;
106 }
107
108 /**
109 * Get the next value (i.e. the first unused value) for this sequence.
110 * @return the next value (i.e. the first unused value) for this sequence.
111 */
112 public long getNextValue() {
113 return nextValue;
114 }
115
116 /**
117 * Set the next value (i.e. the first unused value) for this sequence.
118 * @param nextValue the next value (i.e. the first unused value) for this sequence.
119 */
120 public void setNextValue(long nextValue) {
121 this.nextValue = nextValue;
122 }
123 }