com.helger.phoss.smp.backend.sql.mgr.SMPBusinessCardManagerJDBC Maven / Gradle / Ivy
/*
* Copyright (C) 2019-2024 Philip Helger and contributors
* philip[at]helger[dot]com
*
* 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.
*/
package com.helger.phoss.smp.backend.sql.mgr;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.helger.commons.ValueEnforcer;
import com.helger.commons.annotation.ReturnsMutableCopy;
import com.helger.commons.annotation.ReturnsMutableObject;
import com.helger.commons.callback.CallbackList;
import com.helger.commons.collection.impl.CommonsArrayList;
import com.helger.commons.collection.impl.CommonsHashMap;
import com.helger.commons.collection.impl.CommonsHashSet;
import com.helger.commons.collection.impl.ICommonsList;
import com.helger.commons.collection.impl.ICommonsMap;
import com.helger.commons.collection.impl.ICommonsSet;
import com.helger.commons.mutable.MutableBoolean;
import com.helger.commons.state.EChange;
import com.helger.commons.state.EContinue;
import com.helger.commons.state.ESuccess;
import com.helger.commons.string.StringHelper;
import com.helger.db.jdbc.callback.ConstantPreparedStatementDataProvider;
import com.helger.db.jdbc.executor.DBExecutor;
import com.helger.db.jdbc.executor.DBResultRow;
import com.helger.db.jdbc.mgr.AbstractJDBCEnabledManager;
import com.helger.json.IJson;
import com.helger.json.IJsonArray;
import com.helger.json.IJsonObject;
import com.helger.json.JsonArray;
import com.helger.json.JsonObject;
import com.helger.json.serialize.IJsonWriterSettings;
import com.helger.json.serialize.JsonReader;
import com.helger.json.serialize.JsonWriterSettings;
import com.helger.peppolid.IParticipantIdentifier;
import com.helger.peppolid.factory.IIdentifierFactory;
import com.helger.phoss.smp.domain.SMPMetaManager;
import com.helger.phoss.smp.domain.businesscard.ISMPBusinessCard;
import com.helger.phoss.smp.domain.businesscard.ISMPBusinessCardCallback;
import com.helger.phoss.smp.domain.businesscard.ISMPBusinessCardManager;
import com.helger.phoss.smp.domain.businesscard.SMPBusinessCard;
import com.helger.phoss.smp.domain.businesscard.SMPBusinessCardContact;
import com.helger.phoss.smp.domain.businesscard.SMPBusinessCardEntity;
import com.helger.phoss.smp.domain.businesscard.SMPBusinessCardIdentifier;
import com.helger.phoss.smp.domain.businesscard.SMPBusinessCardName;
import com.helger.photon.audit.AuditHelper;
/**
* A JDBC based implementation of the {@link ISMPBusinessCardManager} interface.
*
* @author Philip Helger
* @since 9.2.4
*/
public final class SMPBusinessCardManagerJDBC extends AbstractJDBCEnabledManager implements ISMPBusinessCardManager
{
private static final Logger LOGGER = LoggerFactory.getLogger (SMPBusinessCardManagerJDBC.class);
// Create with as minimal output as possible
private static final IJsonWriterSettings JWS = JsonWriterSettings.DEFAULT_SETTINGS;
private final CallbackList m_aCBs = new CallbackList <> ();
/**
* Constructor
*
* @param aDBExecSupplier
* The supplier for {@link DBExecutor} objects. May not be
* null
.
*/
public SMPBusinessCardManagerJDBC (@Nonnull final Supplier extends DBExecutor> aDBExecSupplier)
{
super (aDBExecSupplier);
}
@Nonnull
@ReturnsMutableObject
public CallbackList bcCallbacks ()
{
return m_aCBs;
}
@Nonnull
public static IJson getBCIAsJson (@Nullable final List aIDs)
{
final JsonArray ret = new JsonArray ();
if (aIDs != null)
for (final SMPBusinessCardIdentifier aID : aIDs)
ret.add (new JsonObject ().add ("id", aID.getID ())
.add ("scheme", aID.getScheme ())
.add ("value", aID.getValue ()));
return ret;
}
@Nonnull
public static ICommonsList getJsonAsBCI (@Nullable final String sJson)
{
final ICommonsList ret = new CommonsArrayList <> ();
final IJson aJson = sJson == null ? null : JsonReader.readFromString (sJson);
if (aJson != null && aJson.isArray ())
for (final IJson aItem : aJson.getAsArray ())
{
final IJsonObject aItemObject = aItem.getAsObject ();
final SMPBusinessCardIdentifier aBCI = new SMPBusinessCardIdentifier (aItemObject.getAsString ("id"),
aItemObject.getAsString ("scheme"),
aItemObject.getAsString ("value"));
ret.add (aBCI);
}
return ret;
}
@Nonnull
public static IJson getStringAsJson (@Nullable final Iterable aIDs)
{
return new JsonArray ().addAll (aIDs);
}
@Nonnull
public static ICommonsList getJsonAsString (@Nullable final String sJson)
{
final ICommonsList ret = new CommonsArrayList <> ();
final IJson aJson = sJson == null ? null : JsonReader.readFromString (sJson);
if (aJson != null && aJson.isArray ())
for (final IJson aItem : aJson.getAsArray ())
{
final String sValue = aItem.getAsValue ().getAsString ();
ret.add (sValue);
}
return ret;
}
@Nonnull
public static IJson getBCCAsJson (@Nullable final Iterable aIDs)
{
final JsonArray ret = new JsonArray ();
if (aIDs != null)
for (final SMPBusinessCardContact aID : aIDs)
ret.add (new JsonObject ().add ("id", aID.getID ())
.add ("type", aID.getType ())
.add ("name", aID.getName ())
.add ("phone", aID.getPhoneNumber ())
.add ("email", aID.getEmail ()));
return ret;
}
@Nonnull
public static ICommonsList getJsonAsBCC (@Nullable final String sJson)
{
final ICommonsList ret = new CommonsArrayList <> ();
final IJson aJson = sJson == null ? null : JsonReader.readFromString (sJson);
if (aJson != null && aJson.isArray ())
for (final IJson aItem : aJson.getAsArray ())
{
final IJsonObject aItemObject = aItem.getAsObject ();
final SMPBusinessCardContact aBCC = new SMPBusinessCardContact (aItemObject.getAsString ("id"),
aItemObject.getAsString ("type"),
aItemObject.getAsString ("name"),
aItemObject.getAsString ("phone"),
aItemObject.getAsString ("email"));
ret.add (aBCC);
}
return ret;
}
@Nullable
public ISMPBusinessCard createOrUpdateSMPBusinessCard (@Nonnull final IParticipantIdentifier aParticipantID,
@Nonnull final Collection aEntities)
{
ValueEnforcer.notNull (aParticipantID, "ParticipantID");
ValueEnforcer.notNull (aEntities, "Entities");
if (LOGGER.isDebugEnabled ())
LOGGER.debug ("createOrUpdateSMPBusinessCard (" +
aParticipantID.getURIEncoded () +
", " +
aEntities.size () +
" entities" +
")");
final MutableBoolean aUpdated = new MutableBoolean (false);
final DBExecutor aExecutor = newExecutor ();
final ESuccess eSucces = aExecutor.performInTransaction ( () -> {
// Delete all existing entities
final String sPID = aParticipantID.getURIEncoded ();
final long nDeleted = aExecutor.insertOrUpdateOrDelete ("DELETE FROM smp_bce" + " WHERE pid=?",
new ConstantPreparedStatementDataProvider (sPID));
if (nDeleted > 0)
{
aUpdated.set (true);
if (LOGGER.isDebugEnabled ())
LOGGER.info ("Deleted " + nDeleted + " existing DBBusinessCardEntity rows");
}
for (final SMPBusinessCardEntity aEntity : aEntities)
{
// Single name only
final String sName;
final String sNames;
if (aEntity.isSingleNameWithoutLanguage ())
{
sName = aEntity.names ().getFirstOrNull ().getName ();
sNames = null;
}
else
{
sName = null;
sNames = aEntity.getNamesAsJson ().getAsJsonString ();
}
aExecutor.insertOrUpdateOrDelete ("INSERT INTO smp_bce (id, pid, name, names, country, geoinfo, identifiers, websites, contacts, addon, regdate)" +
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
new ConstantPreparedStatementDataProvider (aEntity.getID (),
sPID,
sName,
sNames,
aEntity.getCountryCode (),
aEntity.getGeographicalInformation (),
getBCIAsJson (aEntity.identifiers ()).getAsJsonString (JWS),
getStringAsJson (aEntity.websiteURIs ()).getAsJsonString (JWS),
getBCCAsJson (aEntity.contacts ()).getAsJsonString (JWS),
aEntity.getAdditionalInformation (),
aEntity.getRegistrationDate ()));
}
});
if (eSucces.isFailure ())
{
if (aUpdated.booleanValue ())
AuditHelper.onAuditModifyFailure (SMPBusinessCard.OT, "set-all", aParticipantID.getURIEncoded ());
else
AuditHelper.onAuditCreateFailure (SMPBusinessCard.OT, aParticipantID.getURIEncoded ());
return null;
}
final SMPBusinessCard aNewBusinessCard = new SMPBusinessCard (aParticipantID, aEntities);
if (LOGGER.isDebugEnabled ())
LOGGER.debug ("Finished createOrUpdateSMPBusinessCard");
if (aUpdated.booleanValue ())
{
AuditHelper.onAuditModifySuccess (SMPBusinessCard.OT,
"set-all",
aParticipantID.getURIEncoded (),
Integer.valueOf (aEntities.size ()));
}
else
{
AuditHelper.onAuditCreateSuccess (SMPBusinessCard.OT,
aParticipantID.getURIEncoded (),
Integer.valueOf (aEntities.size ()));
}
// Invoke generic callbacks
m_aCBs.forEach (x -> x.onSMPBusinessCardCreatedOrUpdated (aNewBusinessCard));
return aNewBusinessCard;
}
@Nonnull
public EChange deleteSMPBusinessCard (@Nullable final ISMPBusinessCard aSMPBusinessCard)
{
if (aSMPBusinessCard == null)
return EChange.UNCHANGED;
if (LOGGER.isDebugEnabled ())
LOGGER.debug ("deleteSMPBusinessCard (" + aSMPBusinessCard.getID () + ")");
final long nCount = newExecutor ().insertOrUpdateOrDelete ("DELETE FROM smp_bce" + " WHERE pid=?",
new ConstantPreparedStatementDataProvider (aSMPBusinessCard.getID ()));
if (nCount <= 0)
{
if (LOGGER.isDebugEnabled ())
LOGGER.debug ("Finished deleteSMPBusinessCard. Change=false");
AuditHelper.onAuditDeleteFailure (SMPBusinessCard.OT, aSMPBusinessCard.getID (), "no-such-id");
return EChange.UNCHANGED;
}
if (LOGGER.isDebugEnabled ())
LOGGER.debug ("Finished deleteSMPBusinessCard. Change=true");
AuditHelper.onAuditDeleteSuccess (SMPBusinessCard.OT,
aSMPBusinessCard.getID (),
Integer.valueOf (aSMPBusinessCard.getEntityCount ()));
// Invoke generic callbacks
m_aCBs.forEach (x -> x.onSMPBusinessCardDeleted (aSMPBusinessCard));
return EChange.CHANGED;
}
@Nonnull
private static EContinue _addNames (@Nonnull final SMPBusinessCardEntity aEntity,
@Nullable final String sName,
@Nullable final String sNames)
{
if (StringHelper.hasText (sNames))
{
// Eventually more then one name - parse JSON
final IJsonArray aJsonArray = JsonReader.builder ().source (sNames).readAsArray ();
if (aJsonArray != null)
for (final IJsonObject aJsonObj : aJsonArray.iteratorObjects ())
{
final SMPBusinessCardName aBCName = SMPBusinessCardName.createFromJson (aJsonObj);
if (aBCName != null)
aEntity.names ().add (aBCName);
}
// Check only once at the end
if (aEntity.names ().isEmpty ())
{
LOGGER.error ("The names of a Business Entity retrieved from the DB (" +
sNames +
") could not be parsed properly to a JSON array of JSON objects. Ignoring Business Entity.");
return EContinue.BREAK;
}
}
else
{
// Single name
aEntity.names ().add (new SMPBusinessCardName (sName, null));
}
return EContinue.CONTINUE;
}
@Nonnull
@ReturnsMutableCopy
public ICommonsList getAllSMPBusinessCards ()
{
final ICommonsList ret = new CommonsArrayList <> ();
final ICommonsList aDBResult = newExecutor ().queryAll ("SELECT id, pid, name, names, country, geoinfo, identifiers, websites, contacts, addon, regdate" +
" FROM smp_bce");
if (aDBResult != null)
{
final IIdentifierFactory aIF = SMPMetaManager.getIdentifierFactory ();
// Group by ID
final ICommonsMap > aEntityMap = new CommonsHashMap <> ();
for (final DBResultRow aRow : aDBResult)
{
final SMPBusinessCardEntity aEntity = new SMPBusinessCardEntity (aRow.getAsString (0));
final String sPID = aRow.getAsString (1);
final IParticipantIdentifier aPID = aIF.parseParticipantIdentifier (sPID);
if (aPID == null)
{
LOGGER.error ("The participant identifier of a Business Entity retrieved from the DB (" +
sPID +
") cannot be parsed properly. Ignoring Business Entity.");
continue;
}
// Single name or multiple names?
final String sName = aRow.getAsString (2);
final String sNames = aRow.getAsString (3);
_addNames (aEntity, sName, sNames);
aEntity.setCountryCode (aRow.getAsString (4));
aEntity.setGeographicalInformation (aRow.getAsString (5));
aEntity.identifiers ().setAll (getJsonAsBCI (aRow.getAsString (6)));
aEntity.websiteURIs ().setAll (getJsonAsString (aRow.getAsString (7)));
aEntity.contacts ().setAll (getJsonAsBCC (aRow.getAsString (8)));
aEntity.setAdditionalInformation (aRow.getAsString (9));
aEntity.setRegistrationDate (aRow.get (10).getAsLocalDate ());
aEntityMap.computeIfAbsent (aPID, k -> new CommonsArrayList <> ()).add (aEntity);
}
// Convert
for (final Map.Entry > aEntry : aEntityMap.entrySet ())
{
final IParticipantIdentifier aPID = aEntry.getKey ();
ret.add (new SMPBusinessCard (aPID, aEntry.getValue ()));
}
}
return ret;
}
@Nonnull
@ReturnsMutableCopy
public ICommonsSet getAllSMPBusinessCardIDs ()
{
final ICommonsSet ret = new CommonsHashSet <> ();
final ICommonsList aDBResult = newExecutor ().queryAll ("SELECT pid" + " FROM smp_bce");
if (aDBResult != null)
for (final DBResultRow aRow : aDBResult)
ret.add (aRow.getAsString (0));
return ret;
}
public boolean containsSMPBusinessCardOfID (@Nullable final IParticipantIdentifier aID)
{
if (aID == null)
return false;
final long nCount = newExecutor ().queryCount ("SELECT COUNT(*) FROM smp_bce" + " WHERE pid=?",
new ConstantPreparedStatementDataProvider (aID.getURIEncoded ()));
return nCount == 1;
}
@Nullable
public ISMPBusinessCard getSMPBusinessCardOfID (@Nullable final IParticipantIdentifier aID)
{
if (aID == null)
return null;
final ICommonsList aDBResult = newExecutor ().queryAll ("SELECT id, name, names, country, geoinfo, identifiers, websites, contacts, addon, regdate" +
" FROM smp_bce" +
" WHERE pid=?",
new ConstantPreparedStatementDataProvider (aID.getURIEncoded ()));
if (aDBResult == null)
return null;
if (aDBResult.isEmpty ())
return null;
final ICommonsList aEntities = new CommonsArrayList <> ();
for (final DBResultRow aRow : aDBResult)
{
final SMPBusinessCardEntity aEntity = new SMPBusinessCardEntity (aRow.getAsString (0));
final String sName = aRow.getAsString (1);
final String sNames = aRow.getAsString (2);
_addNames (aEntity, sName, sNames);
aEntity.setCountryCode (aRow.getAsString (3));
aEntity.setGeographicalInformation (aRow.getAsString (4));
aEntity.identifiers ().setAll (getJsonAsBCI (aRow.getAsString (5)));
aEntity.websiteURIs ().setAll (getJsonAsString (aRow.getAsString (6)));
aEntity.contacts ().setAll (getJsonAsBCC (aRow.getAsString (7)));
aEntity.setAdditionalInformation (aRow.getAsString (8));
aEntity.setRegistrationDate (aRow.get (9).getAsLocalDate ());
aEntities.add (aEntity);
}
return new SMPBusinessCard (aID, aEntities);
}
@Nonnegative
public long getSMPBusinessCardCount ()
{
return newExecutor ().queryCount ("SELECT COUNT (DISTINCT pid) FROM smp_bce");
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy