
org.efaps.update.AbstractUpdate Maven / Gradle / Ivy
/*
* Copyright 2003 - 2012 The eFaps Team
*
* Licensed 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.
*
* Revision: $Rev: 7908 $
* Last Changed: $Date: 2012-08-13 16:39:28 -0500 (Mon, 13 Aug 2012) $
* Last Changed By: $Author: [email protected] $
*/
package org.efaps.update;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.jexl.Expression;
import org.apache.commons.jexl.ExpressionFactory;
import org.apache.commons.jexl.JexlContext;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.efaps.admin.datamodel.Type;
import org.efaps.ci.CIAdmin;
import org.efaps.ci.CIAdminCommon;
import org.efaps.db.Delete;
import org.efaps.db.Insert;
import org.efaps.db.Instance;
import org.efaps.db.InstanceQuery;
import org.efaps.db.MultiPrintQuery;
import org.efaps.db.QueryBuilder;
import org.efaps.db.SelectBuilder;
import org.efaps.db.Update;
import org.efaps.update.event.Event;
import org.efaps.update.util.InstallationException;
import org.efaps.util.EFapsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
/**
*
* This class is the major class for importing or updating of types, commands
* and so on in eFaps.
*
*
* For every kind of Object in eFaps a own class extends this AbstractUpdate. In
* this classes the XML-Files is read and with the digester converted in
* Objects. After reading all Objects of one XML-File the Objects are inserted
* corresponding to the Version.
*
*
* @author The eFaps Team
* @version $Id: AbstractUpdate.java 7908 2012-08-13 21:39:28Z [email protected] $
*/
public abstract class AbstractUpdate
implements IUpdate
{
/**
* Logging instance used to give logging information of this class.
*/
public static final Logger LOG = LoggerFactory.getLogger(AbstractUpdate.class);
/**
* The URL of the xml file is stored in this instance variable.
*/
private final URL url;
/**
* The name of the data model type is store in this instance variable.
*/
private final String dataModelTypeName;
/**
* All known link types are set to this instance variable.
*/
private final Set allLinkTypes;
/**
* The universal unique identifier of the object is stored in this instance
* variable.
*
* @see #setUUID
*/
private String uuid = null;
/**
* Name of the file application for which this XML file is defined.
*
* @see #setFileApplication
*/
private String fileApplication = null;
/**
* Revision of the XML file.
*
* @see #setFileRevision
*/
private String fileRevision = null;
/**
* All definitions of versions are added to this list.
*/
private final List definitions = new ArrayList();
/**
* Default constructor with no defined possible links for given
* _dataModelTypeName
.
*
* @param _url URL of the update file
* @param _dataModelTypeName name of the data model type to update
*/
protected AbstractUpdate(final URL _url,
final String _dataModelTypeName)
{
this(_url, _dataModelTypeName, null);
}
/**
* Default constructor with defined possible links
* _allLinkTypes
for given _dataModelTypeName
.
*
* @param _url URL of the update file
* @param _dataModelTypeName name of the data model type to update
* @param _allLinkTypes all possible type link
*/
protected AbstractUpdate(final URL _url,
final String _dataModelTypeName,
final Set _allLinkTypes)
{
this.url = _url;
this.dataModelTypeName = _dataModelTypeName;
this.allLinkTypes = _allLinkTypes;
}
/**
* Read event for given tags path with attributes and text.
*
* @param _tags tags path as list
* @param _attributes map of attributes for current tag
* @param _text content text of this tags path TODO: error could not be
* thrown because db properties is not read correctly
* @throws SAXException on error
*/
public void readXML(final List _tags,
final Map _attributes,
final String _text)
throws SAXException
{
if (_tags.size() == 1) {
final String value = _tags.get(0);
if ("uuid".equals(value)) {
this.uuid = _text;
} else if ("file-application".equals(value)) {
this.fileApplication = _text;
} else if ("file-revision".equals(value)) {
this.fileRevision = _text;
} else if ("definition".equals(value)) {
this.definitions.add(newDefinition());
}
} else if ("definition".equals(_tags.get(0))) {
final AbstractDefinition curDef = this.definitions.get(this.definitions.size() - 1);
curDef.readXML(_tags.subList(1, _tags.size()), _attributes, _text);
} else {
throw new SAXException("Unknown XML Tag: " + _tags + " for: " + this.url);
}
}
/**
* Creates a new definition instance used from
* {@link #readXML(List, Map, String)}.
*
* @return new definition instance
*/
protected abstract AbstractDefinition newDefinition();
/**
* Adds one definition of a update for a specific version to all definitions
* in {@link #definitions}.
*
* @param _definition definition to add
* @see #definitions
*/
protected void addDefinition(final AbstractDefinition _definition)
{
this.definitions.add(_definition);
}
/**
* The instance method returns the eFaps instance representing the read XML
* configuration. If not already get from the eFaps database, the
* information is read. If no instance exists in the database, a new one is
* automatically created. The method searches for the given universal unique
* identifier in {@link #uuid} the instance in the eFaps database and stores
* the result in {@link #instance}. If no object is found in eFaps,
* {@link #instance} is set to null
. A new instance is created
* in the eFaps DB for given universal unique identifier in {@link #uuid}.
* The name of the access set is also the universal unique identifier,
* because the name of access set is first updates in the version
* definition.
* The new created object is stored as instance information in
* {@link #instance}.
*
* @param _jexlContext context used to evaluate JEXL expressions
* @param _step current step of the update life cycle
* @param _profiles the Profiles assigned
* @throws InstallationException from called update methods
*/
public void updateInDB(final JexlContext _jexlContext,
final UpdateLifecycle _step,
final Set _profiles)
throws InstallationException
{
for (final AbstractDefinition def : this.definitions) {
if (def.isValidVersion(_jexlContext)
&& (def.getProfiles().isEmpty()
|| CollectionUtils.containsAny(_profiles, def.getProfiles()))) {
if ((this.url != null) && AbstractUpdate.LOG.isDebugEnabled()) {
AbstractUpdate.LOG.debug("Executing '" + this.url.toString() + "'");
}
def.updateInDB(_step, this.allLinkTypes);
}
}
}
/**
* This is the getter method for the instance variable {@link #url}.
*
* @return value of instance variable {@link #url}
*/
protected URL getURL()
{
return this.url;
}
/**
* Defines the new {@link #uuid UUID} of the updated object.
*
* @param _uuid new UUID for the object to update
* @see #uuid
*/
protected void setUUID(final String _uuid)
{
this.uuid = _uuid;
}
/**
* This is the getter method for instance variable {@link #uuid}.
*
* @return value of instance variable {@link #uuid}
* @see #uuid
* @see #setUUID
*/
protected String getUUID()
{
return this.uuid;
}
/**
* This is the setter method for instance variable {@link #fileApplication}.
*
* @param _fileApplication new value for instance variable
* {@link #fileApplication}
* @see #fileApplication
* @see #getFileApplication
*/
public void setFileApplication(final String _fileApplication)
{
this.fileApplication = _fileApplication;
}
/**
* This is the getter method for instance variable {@link #fileApplication}.
*
* @return value of instance variable {@link #fileApplication}
* @see #fileApplication
* @see #setFileApplication
*/
public String getFileApplication()
{
return this.fileApplication;
}
/**
* This is the setter method for instance variable {@link #fileRevision}.
*
* @param _fileRevision new value for instance variable
* {@link #fileRevision}
* @see #fileRevision
* @see #getFileRevision
*/
public void setFileRevision(final String _fileRevision)
{
this.fileRevision = _fileRevision;
}
/**
* This is the getter method for instance variable {@link #fileRevision}.
*
* @return value of instance variable {@link #fileRevision}
* @see #fileRevision
* @see #setFileRevision
*/
public String getFileRevision()
{
return this.fileRevision;
}
/**
* This is the getter method for instance variable {@link #definitions}.
*
* @return value of instance variable {@link #definitions}
* @see #definitions
*/
protected List getDefinitions()
{
return this.definitions;
}
/**
* This is the getter method for the instance variable
* {@link #dataModelTypeName}.
*
* @return value of instance variable {@link #dataModelTypeName}
*/
public String getDataModelTypeName()
{
return this.dataModelTypeName;
}
/**
* This is the getter method for the instance variable {@link #allLinkTypes}
* .
*
* @return value of instance variable {@link #allLinkTypes}
*/
protected Set getAllLinkTypes()
{
return this.allLinkTypes;
}
/**
* Returns a string representation with values of all instance variables.
*
* @return string representation of this abstract update
*/
@Override
public String toString()
{
return new ToStringBuilder(this).append("uuid", this.uuid).append("fileApplication", this.fileApplication)
.append("fileRevision", this.fileRevision).append("definitions", this.definitions).toString();
}
/**
* The class is used to define the links with all information needed to
* update the link information between the object to update and the related
* objects.
*
* @see #setLinksInDB
*/
protected static class Link
{
/** Name of the link. */
private final String linkName;
/**
* Name of the parent attribute in the link. The parent attribute stores
* the id of the objecto udpate.
*/
private final String parentAttrName;
/**
* Name of the child type used to query for the given name to which a
* link must be set.
*/
private final String childTypeName;
/** Name of the child attribute in the link. */
private final String childAttrName;
/**
* set of key attributes.
*/
private final Set keyAttributes = new HashSet();
/**
* Constructor used to initialize the instance variables.
*
* @param _linkName name of the link itself
* @param _parentAttrName name of the parent attribute in the link
* @param _childTypeName name of the child type
* @param _childAttrName name of the child attribute in the link
* @param _keyAttributes list of attributes used to identify the object
* to be connected default "Name"
* @see #linkName
* @see #parentAttrName
* @see #childTypeName
* @see #childAttrName
*/
public Link(final String _linkName,
final String _parentAttrName,
final String _childTypeName,
final String _childAttrName,
final String... _keyAttributes)
{
this.linkName = _linkName;
this.parentAttrName = _parentAttrName;
this.childTypeName = _childTypeName;
this.childAttrName = _childAttrName;
for (final String keyAttribute : _keyAttributes) {
this.keyAttributes.add(keyAttribute);
}
// set the default if necessary
if (this.keyAttributes.size() < 1) {
this.keyAttributes.add("Name");
}
}
/**
* Child Type extracted from the child type name.
*
* @return child type extracted from the child type name
*/
public Type getChildType()
{
return Type.get(this.childTypeName);
}
/**
* Link Type extracted from the link name.
*
* @return link type extracted from the link name
*/
public Type getLinkType()
{
return Type.get(this.linkName);
}
/**
* Getter method for instance variable {@link #keyAttributes}.
*
* @return value of instance variable {@link #keyAttributes}
*/
public Set getKeyAttributes()
{
return this.keyAttributes;
}
/**
* Returns a string representation with values of all instance variables
* of a link.
*
* @return string representation of this link
*/
@Override
public String toString()
{
return new ToStringBuilder(this).append("linkName", this.linkName).append("parentAttrName",
this.parentAttrName).append("childTypeName", this.childTypeName).append("childAttrName",
this.childAttrName).toString();
}
}
/**
* Some links has a order in the database. This means that the connections
* must be made in the order they are defined in the XML update file.
*/
protected static class OrderedLink
extends AbstractUpdate.Link
{
/**
* @param _linkName name of the link itself
* @param _parentAttrName name of the parent attribute in the link
* @param _childTypeName name of the child type
* @param _childAttrName name of the child attribute in the link
*/
public OrderedLink(final String _linkName,
final String _parentAttrName,
final String _childTypeName,
final String _childAttrName)
{
super(_linkName, _parentAttrName, _childTypeName, _childAttrName);
}
}
/**
*
*/
protected abstract class AbstractDefinition
{
/**
* Expression of this definition if this definition must be installed.
*
* @see #readXML(List, Map, String) defines this expression
* @see #isValidVersion(JexlContext) test this expression
*/
private String expression = null;
/**
* This instance variable stores the type of Definition (default:
* "replace"). Possible values are:
*
* - "replace"
* - "update"
*
*
* @see #getType()
* @see #setType(String)
*/
private String type = "replace";
/**
* The value depending on the attribute name for this definition.
*
* @see #addValue
* @see #getValue
*/
private final Map values = new HashMap();
/**
* Property value depending on the property name for this definition.
*
* @see #addProperty.
*/
private final Map properties = new HashMap();
/**
*
*/
private final Map> links = new HashMap>();
/**
* Name of attribute by which the search in the database is done. If not
* specified (defined to null
), the attribute
* "UUID" is used.
*
* @see #searchInstance
*/
private final String searchAttrName;
/**
* list of events.
*/
private final List events = new ArrayList();
/**
* Instance of this definition.
*/
private Instance instance = null;
/**
* Profiles this Definition is activated for.
*/
private final Set profiles = new HashSet();
/**
* Default constructor for the attribute by which the object is searched
* is "UUID".
*/
protected AbstractDefinition()
{
this(null);
}
/**
* Constructor defining the search attribute.
*
* @param _searchAttrName name of attribute by which the object is
* searched
* @see #searchInstance method using the search attribute
* @see #searchAttrName
*/
protected AbstractDefinition(final String _searchAttrName)
{
this.searchAttrName = _searchAttrName;
}
/**
* @param _tags tag to reas
* @param _attributes attributes
* @param _text text
*/
protected void readXML(final List _tags,
final Map _attributes,
final String _text)
{
final String value = _tags.get(0);
if ("name".equals(value)) {
setName(_text);
} else if ("property".equals(value)) {
this.properties.put(_attributes.get("name"), _text);
} else if ("version-expression".equals(value)) {
this.expression = _text;
} else if ("profiles".equals(value)) {
if (_tags.size() > 1) {
final String subValue = _tags.get(1);
if ("profile".equals(subValue)) {
this.profiles.add(Profile.getProfile(_attributes.get("name")));
}
}
} else {
throw new Error("Unknown Tag '" + _tags + "' (file " + AbstractUpdate.this.url + ")");
}
}
/**
* Evaluates the JEXP expression defined in {@link #expression}. If this
* expression returns true, the definition is a valid version and could
* be executed.
*
* @param _jexlContext context used to evaluate JEXL expressions
* @return true if the definition is valid
* @throws InstallationException if the JEXL expression in {@link #expression}
* could not be evaluated
* @see #expression
*/
public boolean isValidVersion(final JexlContext _jexlContext)
throws InstallationException
{
boolean exec;
try {
if (this.expression == null) {
final Expression jexlExpr = ExpressionFactory.createExpression("version==latest");
exec = Boolean.parseBoolean(jexlExpr.evaluate(_jexlContext).toString());
} else {
final Expression jexlExpr = ExpressionFactory.createExpression(this.expression);
exec = Boolean.parseBoolean(jexlExpr.evaluate(_jexlContext).toString());
}
//CHECKSTYLE:OFF
} catch (final Exception e) {
//CHECKSTYLE:ON
throw new InstallationException("isValidVersion.JEXLExpressionNotEvaluatable", e);
}
return exec;
}
/**
* In case that this Definition does not have a profile assigned,
* the Default Profile will be assigned on the first call of this method.
* @param _profile Profile to be checked
* @return true if this Definition belongs to the given Profile,
* else false
*/
public boolean assignedTo(final Profile _profile)
{
return this.profiles.isEmpty() ? true : this.profiles.contains(_profile);
}
/**
* @param _step current update step
* @param _allLinkTypes set of all type of links
* @throws InstallationException if update failed TODO: do not throw
* EFapsException
*/
protected void updateInDB(final UpdateLifecycle _step,
final Set _allLinkTypes)
throws InstallationException
{
if (_step == UpdateLifecycle.EFAPS_CREATE) {
searchInstance();
// if no instance exists, a new insert must be done
if (this.instance == null) {
final Insert insert;
try {
insert = new Insert(AbstractUpdate.this.dataModelTypeName);
insert.add("UUID", AbstractUpdate.this.uuid);
} catch (final EFapsException e) {
throw new InstallationException("Initialize for the insert of '"
+ AbstractUpdate.this.dataModelTypeName + "' with UUID '"
+ AbstractUpdate.this.uuid + "' failed", e);
}
createInDB(insert);
}
} else if (_step == UpdateLifecycle.EFAPS_UPDATE) {
try {
final String name = this.values.get("Name");
final Update update = new Update(this.instance);
if (this.instance.getType().getAttribute("Revision") != null) {
update.add("Revision", AbstractUpdate.this.fileRevision);
}
for (final Map.Entry entry : this.values.entrySet()) {
update.add(entry.getKey(), entry.getValue());
}
if (AbstractUpdate.LOG.isInfoEnabled() && (name != null)) {
AbstractUpdate.LOG.info(" Update " + this.instance.getType().getName() + " '" + name + "'");
}
update.executeWithoutAccessCheck();
if (_allLinkTypes != null) {
for (final Link linkType : _allLinkTypes) {
setLinksInDB(this.instance, linkType, this.links.get(linkType));
}
}
setPropertiesInDb(this.instance, this.properties);
for (final Event event : this.events) {
final Instance newInstance = event.updateInDB(this.instance, getValue("Name"));
setPropertiesInDb(newInstance, event.getProperties());
}
} catch (final EFapsException e) {
throw new InstallationException("update did not work", e);
}
}
}
/**
* Search for given data model type. If an attribute name for the search
* is defined in {@link #searchAttrName}, the search is done with this
* given attribute. If no attribute name is defined (value is
* null
, the method searches for given UUID. The result is
* stored in {@link #instance} (or set to null, if not found).
* The search is only done, if no instance is defined (meaning if
* {@link #instance} has no value).
*
* @see #instance variable in which the search result is stored (and the
* search is only done if the value is null
)
* @see #searchAttrName name of the attribute which them the search is
* done
* @throws InstallationException if search for the instance failed
*/
protected void searchInstance()
throws InstallationException
{
if (this.instance == null) {
try {
final QueryBuilder queryBldr = new QueryBuilder(Type.get(AbstractUpdate.this.dataModelTypeName));
if (this.searchAttrName == null) {
queryBldr.addWhereAttrEqValue("UUID", AbstractUpdate.this.uuid);
} else {
queryBldr.addWhereAttrEqValue(this.searchAttrName, this.values.get(this.searchAttrName));
}
final InstanceQuery query = queryBldr.getQuery();
query.executeWithoutAccessCheck();
if (query.next()) {
this.instance = query.getCurrentValue();
}
} catch (final EFapsException e) {
throw new InstallationException("Search for '" + AbstractUpdate.this.dataModelTypeName + "' for '"
+ ((this.searchAttrName == null)
? AbstractUpdate.this.uuid
: this.values.get(this.searchAttrName))
+ "' failed", e);
}
}
}
/**
* Inserts current instance defined by _insert
into the
* eFaps database without any access check.
*
* @param _insert insert instance
* @throws InstallationException if insert failed
*/
protected void createInDB(final Insert _insert)
throws InstallationException
{
try {
if (_insert.getInstance().getType().getAttribute("Revision") != null) {
_insert.add("Revision", AbstractUpdate.this.fileRevision);
}
final String name = this.values.get("Name");
_insert.add("Name", (name == null) ? "-" : name);
if (AbstractUpdate.LOG.isInfoEnabled()) {
AbstractUpdate.LOG.info(" Insert " + _insert.getInstance().getType().getName()
+ " '" + name + "'");
}
_insert.executeWithoutAccessCheck();
} catch (final EFapsException e) {
throw new InstallationException("Insert for '" + _insert.getInstance().getType().getName()
+ "' '" + this.values.get("Name") + " failed", e);
}
this.instance = _insert.getInstance();
}
/**
* Remove all links from given object (defined by the instance).
*
* @param _instance instance for which all links must be removed
* @param _linkType type of link which must be removed
* @throws EFapsException if existing links could not be removed
* (deleted)
* @see #setLinksInDB used to remove all links for given instance with a
* zero length set of link instances
*/
protected void removeLinksInDB(final Instance _instance,
final Link _linkType)
throws EFapsException
{
setLinksInDB(_instance, _linkType, new HashSet());
}
/**
* Sets the links from this object to the given list of objects (with
* the object name) in the eFaps database.
*
* @param _instance instance for which the links must be defined
* @param _linktype type of the link to be updated
* @param _links all links of the type _linktype which will be connected
* to this instance
* @throws EFapsException if links could not be defined
*/
protected void setLinksInDB(final Instance _instance,
final Link _linktype,
final Set _links)
throws EFapsException
{
final Map existing = new HashMap();
boolean order = false;
// only if new Links are given something must be done
if (_links != null) {
final List allLinks = new ArrayList();
// add the existing Links as LinkInstance to the List of all
// Links
final QueryBuilder queryBldr = new QueryBuilder(Type.get(_linktype.linkName));
queryBldr.addWhereAttrEqValue(_linktype.parentAttrName, _instance.getId());
final MultiPrintQuery multi = queryBldr.getPrint();
multi.addAttribute("Type", "OID" , "ID");
final SelectBuilder selId = new SelectBuilder().linkto(_linktype.childAttrName).id();
final SelectBuilder selType = new SelectBuilder().linkto(_linktype.childAttrName).type();
multi.addSelect(selId, selType);
for (final String attrName : _linktype.getKeyAttributes()) {
final SelectBuilder selAttr = new SelectBuilder().linkto(_linktype.childAttrName)
.attribute(attrName);
multi.addSelect(selAttr);
}
multi.executeWithoutAccessCheck();
while (multi.next()) {
final Type tempType = multi.getCurrentInstance().getType();
final Type childType = multi.getSelect(selType);
// check if this is a correct Link for this LinkType
if (tempType.isKindOf(_linktype.getLinkType()) && childType.isKindOf(_linktype.getChildType())) {
final LinkInstance oldLink = new LinkInstance();
for (final String attrName : _linktype.getKeyAttributes()) {
final SelectBuilder selAttr = new SelectBuilder().linkto(_linktype.childAttrName)
.attribute(attrName);
final Object ob = multi.getSelect(selAttr);
String tmp;
if (ob instanceof Type) {
tmp = ((Long) ((Type) ob).getId()).toString();
} else {
tmp = (String) ob;
}
oldLink.getKeyAttr2Value().put(attrName, tmp);
}
final long childId = multi.getSelect(selId);
oldLink.setChildId(childId);
oldLink.setOid(multi.getAttribute("OID"));
oldLink.setId(multi.getAttribute("ID"));
allLinks.add(oldLink);
existing.put(childId, oldLink);
}
}
// add the new LinkInstances to the List of all Linkinstances
for (final LinkInstance onelink : _links) {
// search the id for the Linked Object
final QueryBuilder queryBldr2 = new QueryBuilder(Type.get(_linktype.childTypeName));
for (final Entry entry : onelink.getKeyAttr2Value().entrySet()) {
queryBldr2.addWhereAttrEqValue(entry.getKey(), entry.getValue());
}
final InstanceQuery query = queryBldr2.getQuery();
query.executeWithoutAccessCheck();
if (query.next()) {
final Long id = query.getCurrentValue().getId();
if (id != null) {
boolean add = true;
if (existing.get(id) != null) {
existing.get(id).setUpdate(true);
existing.get(id).setValues(onelink.getValuesMap());
add = false;
}
if (add) {
onelink.setChildId(id);
onelink.setInsert(true);
if (onelink.getOrder() == 0) {
allLinks.add(onelink);
} else {
allLinks.add(onelink.getOrder() - 1, onelink);
order = true;
}
}
}
} else {
AbstractUpdate.LOG.error(_linktype.childTypeName + " '" + onelink.getKeyAttr2Value()
+ "' not found!");
}
}
final Map orderid = new TreeMap();
if (order) {
for (final LinkInstance onelink : allLinks) {
if (onelink.getId() != null) {
orderid.put(onelink.getId(), onelink);
}
}
int i = 0;
for (final Entry entry : orderid.entrySet()) {
// if they are the same don't do anything
if (!entry.getValue().equals(allLinks.get(i))) {
final Update update = new Update(entry.getValue().getOid());
update.add(_linktype.childAttrName, "" + allLinks.get(i).getChildId());
update.executeWithoutAccessCheck();
}
i++;
}
for (int j = i; j < allLinks.size(); j++) {
final Insert insert = new Insert(_linktype.linkName);
insert.add(_linktype.parentAttrName, "" + _instance.getId());
insert.add(_linktype.childAttrName, "" + allLinks.get(j).getChildId());
insert.executeWithoutAccessCheck();
}
} else {
// insert, update the LinkInstances or in case of replace
// remove them
for (final LinkInstance onelink : allLinks) {
if (onelink.isUpdate()) {
final Update update = new Update(_linktype.getChildType(), onelink.getChildId().toString());
for (final Map.Entry value : onelink.getValuesMap().entrySet()) {
update.add(value.getKey(), value.getValue());
}
update.executeWithoutAccessCheck();
} else if (onelink.isInsert()) {
final Insert insert = new Insert(_linktype.linkName);
insert.add(_linktype.parentAttrName, "" + _instance.getId());
insert.add(_linktype.childAttrName, "" + onelink.getChildId());
for (final Map.Entry value : onelink.getValuesMap().entrySet()) {
insert.add(value.getKey(), value.getValue());
}
insert.executeWithoutAccessCheck();
onelink.setOid(insert.getInstance().getOid());
} else {
if (!getType().equals("update") && onelink.getOid() != null) {
final Delete del = new Delete(onelink.getOid());
del.executeWithoutAccessCheck();
}
}
}
}
}
}
/**
* The properties are only set if the object to update could own
* properties (meaning derived from 'Admin_Abstract').
*
* @param _instance instance for which the properties must be set
* @param _properties new properties to set
* @throws EFapsException if properties could not be set TODO: rework of
* the update algorithm (not always a complete delete and
* and new create is needed) TODO: description
*/
protected void setPropertiesInDb(final Instance _instance,
final Map _properties)
throws EFapsException
{
if (_instance.getType().isKindOf(CIAdmin.Abstract.getType())) {
// remove old properties
final QueryBuilder queryBldr = new QueryBuilder(CIAdminCommon.Property);
queryBldr.addWhereAttrEqValue(CIAdminCommon.Property.Abstract, _instance.getId());
final InstanceQuery query = queryBldr.getQuery();
query.executeWithoutAccessCheck();
while (query.next()) {
new Delete(query.getCurrentValue()).executeWithoutAccessCheck();
}
// add current properites
if (_properties != null) {
for (final Map.Entry entry : _properties.entrySet()) {
final Insert insert = new Insert("Admin_Common_Property");
insert.add("Name", entry.getKey());
insert.add("Value", entry.getValue());
insert.add("Abstract", "" + _instance.getId());
insert.executeWithoutAccessCheck();
}
}
}
}
/**
* @param _link link type
* @param _linkinstance name of the object which is linked to and values
* in the link itself (or null)
*/
protected void addLink(final Link _link,
final LinkInstance _linkinstance)
{
Set oneLink = this.links.get(_link);
if (oneLink == null) {
if (_link instanceof OrderedLink) {
oneLink = new LinkedHashSet();
} else {
oneLink = new HashSet();
}
this.links.put(_link, oneLink);
}
oneLink.add(_linkinstance);
}
/**
* @param _linkType type the links are wanted for
* @return Set of links
*/
public Set getLinks(final Link _linkType)
{
return this.links.get(_linkType);
}
/**
* @param _name name of the attribute
* @param _value value of the attribute
* @see #values
*/
protected void addValue(final String _name,
final String _value)
{
this.values.put(_name, _value);
}
/**
* @param _name name of the attribute
* @return value of the set attribute value in this definition
* @see #values
*/
protected String getValue(final String _name)
{
return this.values.get(_name);
}
/**
* @param _name Name ot set
*/
protected void setName(final String _name)
{
addValue("Name", _name);
}
/**
* Returns a string representation with values of all instance variables
* of a definition.
*
* @return string representation of this definition of an access type
* update
*/
@Override
public String toString()
{
return ToStringBuilder.reflectionToString(this);
}
/**
* Adds a trigger _event
to this definition.
*
* @param _event trigger event to add
* @see #events
*/
protected void addEvent(final Event _event)
{
this.events.add(_event);
}
/**
* This is the getter method for the instance variable {@link #events}.
*
* @return value of instance variable {@link #events}
*/
public List getEvents()
{
return this.events;
}
/**
* This is the getter method for the instance variable
* {@link #properties}.
*
* @return value of instance variable {@link #properties}
*/
public Map getProperties()
{
return this.properties;
}
/**
* This is the getter method for the instance variable {@link #type}.
*
* @return value of instance variable {@link #type}
*/
public String getType()
{
return this.type;
}
/**
* This is the getter method for the instance variable {@link #instance}.
*
* @return value of instance variable {@link #instance}
*/
protected Instance getInstance()
{
return this.instance;
}
/**
* This is the setter method for the instance variable {@link #instance}.
*
* @param _instance value for instance variable {@link #instance}
*/
protected void setInstance(final Instance _instance)
{
this.instance = _instance;
}
/**
* This is the setter method for the instance variable {@link #type}.
*
* @param _type the type to set
*/
public void setType(final String _type)
{
this.type = _type;
}
/**
* Getter method for the instance variable {@link #profiles}.
*
* @return value of instance variable {@link #profiles}
*/
public Set getProfiles()
{
return this.profiles;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy