Skip to main content
summaryrefslogtreecommitdiffstats
blob: 3010935327b65bc805b29ef005defc242152c083 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*******************************************************************************
 * Copyright (c) 2012 Boeing.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Boeing - initial API and implementation
 *******************************************************************************/
package org.eclipse.osee.orcs.db.internal.callable;

import static org.eclipse.osee.framework.database.core.IOseeStatement.MAX_FETCH;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Callable;
import org.eclipse.osee.framework.core.enums.ModificationType;
import org.eclipse.osee.framework.core.enums.TransactionDetailsType;
import org.eclipse.osee.framework.core.enums.TxChange;
import org.eclipse.osee.framework.core.exception.OseeExceptions;
import org.eclipse.osee.framework.core.model.Branch;
import org.eclipse.osee.framework.core.model.BranchFactory;
import org.eclipse.osee.framework.core.model.TransactionRecord;
import org.eclipse.osee.framework.core.model.TransactionRecordFactory;
import org.eclipse.osee.framework.core.model.cache.BranchCache;
import org.eclipse.osee.framework.core.model.cache.TransactionCache;
import org.eclipse.osee.framework.database.IOseeDatabaseService;
import org.eclipse.osee.framework.database.core.IOseeStatement;
import org.eclipse.osee.framework.database.core.OseeConnection;
import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
import org.eclipse.osee.framework.jdk.core.util.GUID;
import org.eclipse.osee.framework.jdk.core.util.time.GlobalTime;
import org.eclipse.osee.logger.Log;
import org.eclipse.osee.orcs.OrcsSession;
import org.eclipse.osee.orcs.data.CreateBranchData;
import org.eclipse.osee.orcs.db.internal.accessor.UpdatePreviousTxCurrent;
import org.eclipse.osee.orcs.db.internal.sql.RelationalConstants;
import org.eclipse.osee.orcs.db.internal.util.IdUtil;

/**
 * the behavior of this class - it needs to: have a branch
 * 
 * @author David Miller
 */
public final class BranchCopyTxCallable extends AbstractDatastoreTxCallable<Branch> {

   private final BranchCache branchCache;
   private final TransactionCache txCache;
   private final BranchFactory branchFactory;
   private final TransactionRecordFactory txFactory;
   private final CreateBranchData branchData;
   private Branch internalBranch;

   private static final String INSERT_TX_DETAILS =
      "INSERT INTO osee_tx_details (branch_id, transaction_id, osee_comment, time, author, tx_type) VALUES (?,?,?,?,?,?)";

   private static final String INSERT_ADDRESSING =
      "INSERT INTO osee_txs (transaction_id, gamma_id, mod_type, tx_current, branch_id) VALUES (?,?,?,?,?)";

   private static final String SELECT_ADDRESSING =
      "SELECT gamma_id, mod_type FROM osee_txs txs WHERE txs.branch_id = ? AND txs.transaction_id = ?";

   public BranchCopyTxCallable(Log logger, OrcsSession session, IOseeDatabaseService databaseService, BranchCache branchCache, TransactionCache txCache, BranchFactory branchFactory, TransactionRecordFactory txFactory, CreateBranchData branchData) {
      super(logger, session, databaseService, String.format("Create Branch %s", branchData.getName()));
      this.branchCache = branchCache;
      this.txCache = txCache;
      this.branchFactory = branchFactory;
      this.txFactory = txFactory;
      this.branchData = branchData;
      //this.systemUserId = -1;
   }

   private TransactionCache getTxCache() {
      return txCache;
   }

   private BranchCache getBranchCache() {
      return branchCache;
   }

   @SuppressWarnings("unchecked")
   @Override
   public Branch handleTxWork(OseeConnection connection) throws OseeCoreException {
      // get the previous transaction, if there is one
      int sourceTx = IdUtil.getSourceTxId(branchData, txCache);
      TransactionRecord savedTx = txCache.getOrLoad(sourceTx);

      TransactionRecord priorTx = txCache.getPriorTransaction(savedTx);
      // copy the branch up to the prior transaction - the goal is to have the provided
      // transaction available on the new branch for merging or comparison purposes
      // first set aside the transaction

      branchData.setFromTransaction(priorTx);

      Callable<Branch> callable =
         new CreateBranchDatabaseTxCallable(getLogger(), getSession(), getDatabaseService(), getBranchCache(),
            getTxCache(), branchFactory, txFactory, branchData);

      try {
         internalBranch = callable.call();
         // TODO figure out if this call is "stackable", is the data passed in above
         // still valid after the branch creation, or do I need to get it all from the new branch???

         String guid = branchData.getGuid();
         if (!GUID.isValid(guid)) {
            guid = GUID.create();
         }

         Timestamp timestamp = GlobalTime.GreenwichMeanTimestamp();
         int nextTransactionId = getDatabaseService().getSequence().getNextTransactionId();

         String creationComment = branchData.getCreationComment() + " and copied transaction " + savedTx.getId();

         getDatabaseService().runPreparedUpdate(connection, INSERT_TX_DETAILS, internalBranch.getId(),
            nextTransactionId, creationComment, timestamp, branchData.getUserArtifactId(),
            TransactionDetailsType.NonBaselined.getId());

         TransactionRecord record =
            txFactory.create(nextTransactionId, internalBranch.getId(), creationComment, timestamp,
               branchData.getUserArtifactId(), RelationalConstants.ART_ID_SENTINEL, TransactionDetailsType.Baselined,
               branchCache);

         txCache.cache(record);

         populateTransaction(0.30, connection, record.getId(), internalBranch, savedTx);

         UpdatePreviousTxCurrent updater =
            new UpdatePreviousTxCurrent(getDatabaseService(), connection, internalBranch.getId());
         updater.updateTxNotCurrentsFromTx(record.getId());

      } catch (Exception ex) {
         OseeExceptions.wrapAndThrow(ex);
      }
      return internalBranch;
   }

   private void populateTransaction(double workAmount, OseeConnection connection, int intoTx, Branch branch, TransactionRecord copyTx) throws OseeCoreException {
      List<Object[]> data = new ArrayList<Object[]>();
      HashSet<Integer> gammas = new HashSet<Integer>(100000);
      long parentBranchId = RelationalConstants.BRANCH_SENTINEL;
      if (branch.hasParentBranch()) {
         parentBranchId = branch.getParentBranch().getId();
      }
      int copyTxId = copyTx.getId();

      populateAddressingToCopy(connection, data, intoTx, gammas, SELECT_ADDRESSING, parentBranchId, copyTxId);

      if (!data.isEmpty()) {
         getDatabaseService().runBatchUpdate(connection, INSERT_ADDRESSING, data);
      }

      checkForCancelled();
   }

   private void populateAddressingToCopy(OseeConnection connection, List<Object[]> data, int baseTxId, HashSet<Integer> gammas, String query, Object... parameters) throws OseeCoreException {
      IOseeStatement chStmt = getDatabaseService().getStatement(connection);
      try {
         chStmt.runPreparedQuery(MAX_FETCH, query, parameters);
         while (chStmt.next()) {
            checkForCancelled();
            Integer gamma = chStmt.getInt("gamma_id");
            if (!gammas.contains(gamma)) {
               ModificationType modType = ModificationType.getMod(chStmt.getInt("mod_type"));
               TxChange txCurrent = TxChange.getCurrent(modType);
               data.add(new Object[] {baseTxId, gamma, modType.getValue(), txCurrent.getValue(), internalBranch.getId()});
               gammas.add(gamma);
            }
         }
      } finally {
         chStmt.close();
      }
   }
}

Back to the top