Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.jdbc.kernel;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.Strategy;
import org.apache.openjpa.jdbc.meta.Version;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Row;
import org.apache.openjpa.jdbc.sql.RowImpl;
import org.apache.openjpa.jdbc.sql.RowManager;
import org.apache.openjpa.jdbc.sql.SQLExceptions;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.PCState;
import org.apache.openjpa.kernel.StateManagerImpl;
import org.apache.openjpa.lib.conf.Configurable;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.OptimisticException;
/**
* Base update manager with common functionality.
*
* @author Abe White
*/
public abstract class AbstractUpdateManager
implements UpdateManager, Configurable {
protected JDBCConfiguration conf = null;
protected DBDictionary dict = null;
public void setConfiguration(Configuration conf) {
this.conf = (JDBCConfiguration) conf;
dict = this.conf.getDBDictionaryInstance();
}
public void startConfiguration() {
}
public void endConfiguration() {
}
public Collection flush(Collection states, JDBCStore store) {
Connection conn = store.getConnection();
try {
PreparedStatementManager psMgr = newPreparedStatementManager(store,
conn);
return flush(states, store, psMgr);
} finally {
try { conn.close(); } catch (SQLException se) {}
}
}
protected Collection flush(Collection states, JDBCStore store,
PreparedStatementManager psMgr) {
// run through all the states and update them as necessary
RowManager rowMgr = newRowManager();
Collection customs = new LinkedList();
Collection exceps = psMgr.getExceptions();
Collection mappedByIdStates = new ArrayList();
for (Iterator itr = states.iterator(); itr.hasNext();) {
OpenJPAStateManager obj = (OpenJPAStateManager)itr.next();
if (obj instanceof StateManagerImpl) {
StateManagerImpl sm = (StateManagerImpl) obj;
if (sm.getMappedByIdFields() != null)
mappedByIdStates.add(sm);
else exceps = populateRowManager(sm, rowMgr, store, exceps,
customs);
} else
exceps = populateRowManager(obj, rowMgr, store, exceps,
customs);
}
// flush rows
exceps = flush(rowMgr, psMgr, exceps);
if (mappedByIdStates.size() != 0) {
for (Iterator itr = mappedByIdStates.iterator(); itr.hasNext();) {
StateManagerImpl sm = (StateManagerImpl) itr.next();
exceps = populateRowManager(sm, rowMgr, store, exceps, customs);
}
// flush rows
exceps = flush(rowMgr, psMgr, exceps);
}
// now do any custom mappings
for (Iterator itr = customs.iterator(); itr.hasNext();) {
try {
((CustomMapping) itr.next()).execute(store);
} catch (SQLException se) {
exceps = addException(exceps, SQLExceptions.getStore(se, dict));
} catch (OpenJPAException ke) {
exceps = addException(exceps, ke);
}
}
// return all exceptions
return exceps;
}
/**
* Return a new {@link RowManager}.
*/
protected abstract RowManager newRowManager();
/**
* Return a new {@link PreparedStatementManager}.
*/
protected abstract PreparedStatementManager newPreparedStatementManager(
JDBCStore store, Connection conn);
/**
* Flush all rows of the given row manager. Add exceptions to
* exceps (which may start as null) using
* {@link #addException}. Return exceps.
*/
protected abstract Collection flush(RowManager rowMgr,
PreparedStatementManager psMgr, Collection exceps);
/**
* Populate the row manager with rows to be flushed for the given state.
*
* @param exceps exceptions encountered when flushing will be added to
* this list and returned; the list may be null initially
* @param customs buffer custom mappings
* @return the exceptions list
*/
protected Collection populateRowManager(OpenJPAStateManager sm,
RowManager rowMgr, JDBCStore store, Collection exceps,
Collection customs) {
int action = Row.ACTION_UPDATE;
try {
BitSet dirty;
if (sm.getPCState() == PCState.PNEW && !sm.isFlushed()) {
action = Row.ACTION_INSERT;
insert(sm, (ClassMapping) sm.getMetaData(), rowMgr, store,
customs);
} else if (sm.getPCState() == PCState.PNEWFLUSHEDDELETED
|| sm.getPCState() == PCState.PDELETED) {
action = Row.ACTION_DELETE;
delete(sm, (ClassMapping) sm.getMetaData(), rowMgr, store,
customs);
} else if ((dirty = ImplHelper.getUpdateFields(sm)) != null) {
update(sm, dirty, (ClassMapping) sm.getMetaData(), rowMgr,
store, customs, false);
} else if (sm.isVersionUpdateRequired()) {
updateIndicators(sm, (ClassMapping) sm.getMetaData(), rowMgr,
store, customs, true);
} else if (sm.isVersionCheckRequired()) {
if (!((ClassMapping) sm.getMetaData()).getVersion().
checkVersion(sm, store, false))
exceps = addException(exceps, new OptimisticException(sm.
getManagedInstance()));
}
} catch (SQLException se) {
exceps = addException(exceps, SQLExceptions.getStore(se, dict));
} catch (OpenJPAException ke) {
RowImpl row = (RowImpl) rowMgr.getRow(((ClassMapping) sm.getMetaData()).getTable(), action, sm, false);
if (row != null) {
row.setFlushed(true);
}
exceps = addException(exceps, ke);
}
return exceps;
}
/**
* Add the given exception to the given list, which may start out as null.
*/
protected Collection addException(Collection exceps, Exception err) {
if (exceps == null)
exceps = new LinkedList();
exceps.add(err);
return exceps;
}
/**
* Recursive method to insert the given instance, base class first.
*/
protected void insert(OpenJPAStateManager sm, ClassMapping mapping,
RowManager rowMgr, JDBCStore store, Collection customs)
throws SQLException {
Boolean custom = mapping.isCustomInsert(sm, store);
if (!Boolean.FALSE.equals(custom))
mapping.customInsert(sm, store);
if (Boolean.TRUE.equals(custom))
return;
ClassMapping sup = mapping.getJoinablePCSuperclassMapping();
if (sup != null)
insert(sm, sup, rowMgr, store, customs);
mapping.insert(sm, store, rowMgr);
FieldMapping[] fields = mapping.getDefinedFieldMappings();
if (((StateManagerImpl)sm).getMappedByIdFields() != null) {
// when there is mappedByIdFields, the id field is not
// fully populated. We need to insert other fields first
// so that in the process of inserting other fields,
// the values of mappedById fields can be set into
// the id fields. Once the id fields are fully populated,
// we will then insert the id fields.
fields = reorderFields(fields);
}
BitSet dirty = sm.getDirty();
for (int i = 0; i < fields.length; i++) {
if (dirty.get(fields[i].getIndex())
&& !bufferCustomInsert(fields[i], sm, store, customs)) {
fields[i].insert(sm, store, rowMgr);
}
}
if (sup == null) {
Version vers = mapping.getVersion();
if (!bufferCustomInsert(vers, sm, store, customs))
vers.insert(sm, store, rowMgr);
Discriminator dsc = mapping.getDiscriminator();
if (!bufferCustomInsert(dsc, sm, store, customs))
dsc.insert(sm, store, rowMgr);
}
}
private FieldMapping[] reorderFields(FieldMapping[] fields) {
List pkFmds = new ArrayList();
FieldMapping[] ret = new FieldMapping[fields.length];
int j = 0;
for (int i = 0; i < fields.length; i++) {
if (!fields[i].isPrimaryKey())
ret[j++] = fields[i];
else
pkFmds.add(fields[i]);
}
for (int i = 0; i