Java tutorial
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package de.fiz.ddb.aas.auxiliaryoperations; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.logging.Level; import javax.naming.NameNotFoundException; import javax.naming.NamingException; import javax.naming.directory.AttributeModificationException; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.ldap.InitialLdapContext; import org.apache.commons.lang.StringUtils; import de.fiz.ddb.aas.administration.AasPrincipal; import de.fiz.ddb.aas.administration.ConstEnumOrgStatus; import de.fiz.ddb.aas.administration.Constants; import de.fiz.ddb.aas.administration.Organisation; import de.fiz.ddb.aas.authorization.PrivilegeEnum; import de.fiz.ddb.aas.authorization.Scope; import de.fiz.ddb.aas.auxiliaryobjects.Email; import de.fiz.ddb.aas.exceptions.AASUnauthorizedException; import de.fiz.ddb.aas.security.Authorizable; import de.fiz.ddb.aas.security.PreAuthorize; import de.fiz.ddb.aas.utils.LDAPEngineUtilityOrganisation; import de.fiz.ddb.geocoding.GeoAdresse; import de.fiz.ddb.geocoding.GeoLocationDisplayNameRequest; import de.fiz.ddb.geocoding.GeoLocationType; import de.fiz.ddb.geocoding.GeoRequest; import de.fiz.ddb.geocoding.GeoRequestStatus; import de.fiz.ddb.ldap.connector.LDAPConnector; /** * * @author bk */ public class ThreadOrganisationUpdate extends LDAPEngineUtilityOrganisation implements Callable<Organisation>, Authorizable { private Boolean _updatingOfLicensedOrgs = null; private Boolean _changeOfStatus = null; private Organisation _organisation = null; private AasPrincipal _performer = null; private boolean _privilegesUpdate = false; private Organisation _oldOrganisation = null; private Future<GeoAdresse> _submit = null; private Future<String> _submitGeoLocDisplayName = null; // *************************************************************************** private ThreadOrganisationUpdate(AasPrincipal performer) { this._performer = performer; if (performer == null) { throw new IllegalArgumentException("The contractor is unknown: Performer == null"); } } public ThreadOrganisationUpdate(Organisation pOrganisation, boolean pPrivilegesUpdate, AasPrincipal performer) throws IllegalArgumentException, ExecutionException { this(performer); //check mandatory fields if ((pOrganisation == null) || (pOrganisation.getOIDs() == null)) { throw new IllegalArgumentException("Illegal argument: Organization = " + pOrganisation); } if ((pOrganisation.getDisplayName() == null) || (pOrganisation.getDisplayName().length() == 0)) { throw new IllegalArgumentException( "Failed for add organization: Mandatory field displayName may not be empty or null"); } // check fundingAgency: if ((pOrganisation.getOrgParent() != null) && (pOrganisation.getOrgParent().trim().length() > 0) && (pOrganisation.getFundingAgency() != null) && (pOrganisation.getFundingAgency().trim().length() > 0)) { throw new IllegalArgumentException( "The atrribut 'FundingAgency' for sub-organizations is not permitted"); } //check eMail if (StringUtils.isNotBlank(pOrganisation.getEmail())) { new Email(pOrganisation.getEmail()); } this._organisation = pOrganisation; this._privilegesUpdate = pPrivilegesUpdate; } public ThreadOrganisationUpdate(CountDownLatch pReadyLatch, Organisation pOrganisation, boolean pPrivilegesUpdate, AasPrincipal performer) throws AssertionError, IllegalArgumentException, ExecutionException { this(pOrganisation, pPrivilegesUpdate, performer); } // *************************************************************************** @PreAuthorize(privileges = { PrivilegeEnum.ADMIN_ORG, PrivilegeEnum.ADMIN }, scope = Scope.ORGANIZATION, cacheUpdate = true) public Organisation call() throws NameNotFoundException, AASUnauthorizedException, AttributeModificationException, ExecutionException { try { LOG.log(Level.INFO, "Update an organization with ID: ''{0}''", this._organisation.getOIDs()); ThreadOrganisationRead threadOrganisationRead = new ThreadOrganisationRead(this._organisation.getOIDs(), getPerformer()); threadOrganisationRead.setLicensedOrgs(isUpdatingOfLicensedOrgs()); // -- if not found, throw NameNotFoundException: _oldOrganisation = threadOrganisationRead.call(); if (!isChangeOfStatus()) { if (!_oldOrganisation.getStatus().equals(_organisation.getStatus())) { LOG.log(Level.WARNING, "It is only an explicit change of status possible! The old value '" + _oldOrganisation.getStatus() + "' is put back (The new value was: '" + _organisation.getStatus() + "')."); this._organisation.setStatus(_oldOrganisation.getStatus()); } if (_oldOrganisation.getAddress() != null) { // -- wesentliche Adressdaten wurden gendert: boolean vAddressHasBeenChanged = (!_oldOrganisation.getAddress() .equalsWithoutGeocoding(this._organisation.getAddress())); // -- Abfrageforderung: boolean vQueryRequestForGeocoding = ((Math .abs(this._organisation.getAddress().getLatitude()) <= 1e-6) || (Math.abs(this._organisation.getAddress().getLongitude()) <= 1e-6)); // -- Die Geokoordinaten sollten - dem Input entsprechend, gendert werden: boolean vGeocodingShouldBeChanged = (Math.abs(this._organisation.getAddress().getLatitude() - _oldOrganisation.getAddress().getLatitude()) >= 1e-6) || (Math.abs(this._organisation.getAddress().getLongitude() - _oldOrganisation.getAddress().getLongitude()) >= 1e-6); LOG.log(Level.INFO, "AddressHasBeenChanged = {0}, QueryRequestForGeocoding = {1}, GeocodingShouldBeChanged = {2}", new Object[] { vAddressHasBeenChanged, vQueryRequestForGeocoding, vGeocodingShouldBeChanged }); if ((vQueryRequestForGeocoding) || (vAddressHasBeenChanged && !vGeocodingShouldBeChanged)) { try { GeoRequest vGeoRequest = new GeoRequest(new GeoAdresse(this._organisation.getAddress()), LDAPConnector.getSingletonInstance().getHttpProxy()); vGeoRequest.setAskForLocation(true); // -- should be set by Properties... change it! vGeoRequest.addAcceptLocationType(GeoLocationType.ROOFTOP, GeoLocationType.RANGE_INTERPOLATED, GeoLocationType.GEOMETRIC_CENTER, GeoLocationType.APPROXIMATE); _submit = LDAPConnector.getSingletonInstance().getExecutorServiceOne() .submit(vGeoRequest); } catch (IllegalAccessException ex) { LOG.log(Level.SEVERE, "Error bei Adresse: " + this._organisation.getAddress(), ex); } } else if (vGeocodingShouldBeChanged) { try { GeoLocationDisplayNameRequest vGeoLocDisplayNameRequest = new GeoLocationDisplayNameRequest( this._organisation.getAddress().getLatitude(), this._organisation.getAddress().getLongitude(), LDAPConnector.getSingletonInstance().getHttpProxy() //Proxy.NO_PROXY ); _submitGeoLocDisplayName = LDAPConnector.getSingletonInstance().getExecutorServiceOne() .submit(vGeoLocDisplayNameRequest); //LOG.info("Gestartet: '" + vGeoLocDisplayNameRequest.getUrlBase() + "...'"); } catch (IllegalAccessException ex) { LOG.log(Level.WARNING, this._organisation.getAddress() + " without location display name: " + ex.getMessage()); } } } } this.updateOrg(); } catch (AASUnauthorizedException ex) { LOG.log(Level.SEVERE, ex.getMessage(), ex); throw ex; } finally { try { if ((_submitGeoLocDisplayName != null) && (!_submitGeoLocDisplayName.isDone()) && (!_submitGeoLocDisplayName.isCancelled())) { _submitGeoLocDisplayName.cancel(true); _submitGeoLocDisplayName = null; } } catch (Exception ex) { } try { if ((_submit != null) && (!_submit.isDone()) && (!_submit.isCancelled())) { _submit.cancel(true); _submit = null; } } catch (Exception ex) { } } return this._organisation; } // *************************************************************************** private void updateOrg() throws NameNotFoundException, AASUnauthorizedException, AttributeModificationException, ExecutionException { boolean vChange = false; InitialLdapContext vCtx = null; try { if (this._oldOrganisation == null) { LOG.log(Level.WARNING, "No such organization ''{0}'' with oid: ''{1}''.", new Object[] { this._organisation.getDisplayName(), this._organisation.getOIDs() }); throw new NameNotFoundException("No such organization '" + this._organisation.getDisplayName() + "' with oid: '" + this._organisation.getOIDs() + "'."); } GeoAdresse vGeoAdresse; String vLocalDispalyName = null; if (_submit != null) { // hier ist "GeoLocationDisplayName" breits ausgefhrt try { vGeoAdresse = _submit.get(10, TimeUnit.SECONDS); if (vGeoAdresse.getRequestStatus() == GeoRequestStatus.OK) { this._organisation.getAddress().setLatitude(vGeoAdresse.getLatitude()); this._organisation.getAddress().setLongitude(vGeoAdresse.getLongitude()); this._organisation.getAddress() .setLocationDisplayName(vGeoAdresse.getLocationDisplayName()); } else { LOG.log(Level.WARNING, "GeoRequestStatus: {0}, (organization id: {1})", new Object[] { vGeoAdresse.getRequestStatus(), this._organisation.getOIDs() }); } } catch (InterruptedException ex) { LOG.log(Level.WARNING, "Geocoding request exeption for organization id: " + this._organisation.getOIDs(), ex); } catch (TimeoutException ex) { LOG.log(Level.WARNING, "Geocoding request exeption for organization id: " + this._organisation.getOIDs(), ex); } } else if (_submitGeoLocDisplayName != null) { try { vLocalDispalyName = _submitGeoLocDisplayName.get(5, TimeUnit.SECONDS); this._organisation.getAddress().setLocationDisplayName(vLocalDispalyName); //LOG.info("LocalDisplayName='" + vLocalDispalyName + "'" + vLocalDispalyName + "'"); } catch (InterruptedException ex) { LOG.log(Level.WARNING, this._organisation.getOIDs() + " without location display name: " + ex.getMessage()); } catch (ExecutionException ex) { LOG.log(Level.WARNING, this._organisation.getOIDs() + " without location display name: " + ex.getMessage()); } catch (TimeoutException ex) { LOG.log(Level.WARNING, this._organisation.getOIDs() + " without location display name: " + ex.getMessage()); } } LOG.info("newOIDs: '" + this._organisation.getOIDs() + "'"); LOG.info("oldOIDs: '" + this._oldOrganisation.getOIDs() + "'"); if (this._organisation.getOrgRDN() == null) { // -- Ansonsten eine nicht gesetzte RDN kann zum Knall fhren... this._organisation.setOrgRDN(this._oldOrganisation.getOrgRDN()); } else if (!this._organisation.getOrgRDN().equals(this._oldOrganisation.getOrgRDN())) { // -- Hier ist etwas faul... LOG.log(Level.WARNING, "The organization ''{0}'' has RDN: ''{1}'', but there exist an organization ''{0}'' with RDN: ''{2}''!", new Object[] { this._organisation.getId(), this._organisation.getOrgRDN(), this._oldOrganisation.getOrgRDN() }); throw new NameNotFoundException("No such organization '" + this._organisation.getDisplayName() + "' with oid: '" + this._organisation.getOIDs() + "'."); } if (this.isPrivilegesUpdate()) { Set<PrivilegeEnum> removePrivileges = this.privilegeDiff(this._organisation.getPrivilegesSet(), this._oldOrganisation.getPrivilegesSet()); Set<PrivilegeEnum> addPrivileges = this.privilegeDiff(this._oldOrganisation.getPrivilegesSet(), this._organisation.getPrivilegesSet()); if (!removePrivileges.isEmpty() || !addPrivileges.isEmpty()) { vChange = true; for (PrivilegeEnum p : removePrivileges) { ThreadSinglePrivilegeDelete threadSinglePrivilegeDelete = new ThreadSinglePrivilegeDelete(p, this._organisation, this._performer); threadSinglePrivilegeDelete.call(); } for (PrivilegeEnum p : addPrivileges) { ThreadSinglePrivilegeCreate threadSinglePrivilegeCreate = new ThreadSinglePrivilegeCreate(p, this._organisation, this._performer); threadSinglePrivilegeCreate.call(); } } } Attributes orgAttributes = new BasicAttributes(true); Attributes orgRemoveAttributes = new BasicAttributes(true); if (vChange = this.convertOrganizationToLdapOrgAttrsForUpdate(this._organisation, this._oldOrganisation, orgAttributes, orgRemoveAttributes, getPerformer())) { // -- If any changes, the status is set to 'revised' // but not if status will be explicitly changed or by a update operation on Licenses directory if (!isChangeOfStatus() && !isUpdatingOfLicensedOrgs()) { if ((ConstEnumOrgStatus.approved.equals(this._organisation.getStatus()))) { // -- ...then go retrospectively into "revised" status: this._organisation.setStatus(ConstEnumOrgStatus.revised); orgAttributes.put(Constants.ldap_ddbOrg_Status, String.valueOf(this._organisation.getStatus().name())); } } } // --------------------------------------------------------------------- if (vChange) { // -- Save changes to the corresponding directory: StringBuilder vOrgEntryDN = (isUpdatingOfLicensedOrgs() ? this.getLicensedOrgsDN(this._organisation.getOIDs()) : this.getOrgDN(this._organisation.getOIDs())); LOG.log(Level.INFO, "DEBUG-Info: destination OrgEntryDN = '" + vOrgEntryDN + "'"); vCtx = LDAPConnector.getSingletonInstance().takeCtx(); if (orgRemoveAttributes.size() > 0) { vCtx.modifyAttributes(vOrgEntryDN.toString(), DirContext.REMOVE_ATTRIBUTE, orgRemoveAttributes); } vCtx.modifyAttributes(vOrgEntryDN.toString(), DirContext.REPLACE_ATTRIBUTE, orgAttributes); } else { throw new AttributeModificationException( "Not modified: oid = '" + this._organisation.getOIDs() + "'"); } } catch (RejectedExecutionException ex) { LOG.log(Level.SEVERE, "RejectedExecutionException\n{0}", ex); throw new ExecutionException(ex.getMessage(), ex.getCause()); } catch (IllegalAccessException ex) { LOG.log(Level.SEVERE, "Connection-Error\n{0}", ex); throw new ExecutionException(ex.getMessage(), ex.getCause()); } catch (NameNotFoundException ex) { LOG.log(Level.WARNING, null, ex); throw ex; } catch (AttributeModificationException ex) { LOG.log(Level.WARNING, "AttributeModificationException\n{0}", ex.getMessage()); // !!!!AttributeModificationException extends NamingExeption: //throw ex; throw new AttributeModificationException(ex.getMessage()); } catch (NamingException ne) { LOG.log(Level.SEVERE, "NamingException\n{0}", ne); throw new ExecutionException(ne.getMessage(), ne.getCause()); } finally { if (vCtx != null) { try { LDAPConnector.getSingletonInstance().putCtx(vCtx); } catch (Exception ex) { LOG.log(Level.SEVERE, "Exception", ex); } } } } // *************************************************************************** /** * @return the _privilegesUpdate */ public boolean isPrivilegesUpdate() { return _privilegesUpdate; } /** * @param privilegesUpdate the _privilegesUpdate to set */ public void setPrivilegesUpdate(boolean privilegesUpdate) { this._privilegesUpdate = privilegesUpdate; } public AasPrincipal getPerformer() { return _performer; } public String getResourceId() { if (_organisation != null) { return _organisation.getId(); } return null; } // *************************************************************************** /** * @return the _copyingOfOrgs */ public boolean isUpdatingOfLicensedOrgs() { return (_updatingOfLicensedOrgs != null ? _updatingOfLicensedOrgs.booleanValue() : false); } /** * @param _updatingOfLicensedOrgs the _updatingOfLicensedOrgs to set */ public void setUpdatingOfLicensedOrgs(boolean _updatingOfLicensedOrgs) { this._updatingOfLicensedOrgs = _updatingOfLicensedOrgs; } // *************************************************************************** /** * @return the _changeOfStatus */ public boolean isChangeOfStatus() { return (_changeOfStatus != null ? _changeOfStatus.booleanValue() : false); } /** * @param _changeOfStatus the _changeOfStatus to set */ public void setChangeOfStatus(boolean _changeOfStatus) { this._changeOfStatus = _changeOfStatus; } }