/*
* InstantiateSRS.java
*
* This file is part of the SRCM module.
* Copyright (c) 2012-2013 "University of Trento - DISI" All rights reserved.
*
* Is strictly forbidden to remove this copyright notice from this source code.
*
* Disclaimer of Warranty:
* SRCM (this software) is provided "as-is" and without warranty of any kind,
* express, implied or otherwise, including without limitation, any warranty of
* merchantability or fitness for a particular purpose.
* In no event shall the copyright holder or contributors be liable for any direct,
* indirect, incidental, special, exemplary, or consequential damages
* including, but not limited to, procurement of substitute goods or services;
* loss of use, data, or profits; or business interruption) however caused and on
* any theory of liability, whether in contract, strict liability, or tort (including
* negligence or otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3
* as published by the Free Software Foundation with the addition of the
* following permission added to Section 15 as permitted in Section 7(a):
* FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
* "University of Trento - DISI","University of Trento - DISI" DISCLAIMS THE
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* See the GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, see http://www.gnu.org/licenses or write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA, 02110-1301 USA.
*
* For more information, please contact Mattia Salnitri group at this
* address: mattia.salnitri@unitn.it
*
*/
package eu.aniketos.srcm.functional;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
import eu.aniketos.SecureBPMN.EABPM;
import eu.aniketos.SecureBPMN.Participant;
import eu.aniketos.SecureBPMN.Variable;
import eu.aniketos.srcm.SRS.Actor;
import eu.aniketos.srcm.SRS.Agent;
import eu.aniketos.srcm.SRS.Commitment;
import eu.aniketos.srcm.SRS.FullyAuthorized;
import eu.aniketos.srcm.SRS.Goal;
import eu.aniketos.srcm.SRS.Information;
import eu.aniketos.srcm.SRS.NonDisclosure;
import eu.aniketos.srcm.SRS.NonModification;
import eu.aniketos.srcm.SRS.NonProduction;
import eu.aniketos.srcm.SRS.NonRepudiation;
import eu.aniketos.srcm.SRS.NonUsage;
import eu.aniketos.srcm.SRS.Owns;
import eu.aniketos.srcm.SRS.Role;
import eu.aniketos.srcm.SRS.SRS;
import eu.aniketos.srcm.SRS.TangibleBy;
import eu.aniketos.srcm.SRS.Trustworthiness;
import eu.aniketos.srcm.mapping.IsA;
import eu.aniketos.srcm.mapping.Mapping;
import eu.aniketos.srcm.mapping.Plays;
import eu.aniketos.srcm.mapping.Represents;
/**This class manages the SRS instantiation
* @author Mattia Salnitri
*
*/
public class InstantiateSRS
{
//instantiate the srs, it modify directly the SRS
@SuppressWarnings({ "unchecked", "rawtypes" })
void instantiateSRS(SRS srs, Mapping mapping, EABPM bpm, HashSet<Commitment> undecCommitmentList) throws Exception
{
//retrieve the list of object that have to be instantiated
//i clone them couse i will modify the srs lists during the inspection of the local list copies
HashMap<String, Role> roleList = (HashMap<String, Role>) srs.getRoleList().clone();
HashMap<String, Agent> agentList = (HashMap<String, Agent>) srs.getAgentList().clone();
HashMap<String, Goal> goalList = (HashMap<String, Goal>) srs.getGoalList().clone();
HashMap<String, Information> informationList = (HashMap<String, Information>) srs.getInformationList().clone();
HashMap<String, eu.aniketos.srcm.SRS.Document> documentList = (HashMap<String, eu.aniketos.srcm.SRS.Document>) srs.getDocumentList().clone();
Vector<Commitment> commList = (Vector<Commitment>) srs.getCommitmentList().clone();
//attention: all list are cloned
/*
* ATTENTION:
* in commitment
* debtor: is the responsible of the commitment, i.e. who must change the world to sat the post condition of the commitment, if the precondition are true
* creditor: is the requester of the commitment
*/
//get rid of all debtors
Iterator<Commitment> i = commList.iterator();
//for all commitments
while(i.hasNext())
{
Commitment commitment = i.next();
//instantiate deb
HashSet<Participant> partSet = new HashSet<Participant>();
Actor deb = commitment.getDebtor();
//if it's a role i have to search also in the plays relations
if (commitment.getDebtor().getClass()==Role.class)
{
Vector<Plays> playsList = mapping.getPlaysList();
Iterator<Plays> playsIT = playsList.iterator();
while (playsIT.hasNext())
{
Plays plays = playsIT.next();
if (plays.getActor().getId()==deb.getId())
partSet.add(plays.getParticipant());
}
}
Vector<IsA> isaList = mapping.getIsaList();
Iterator<IsA> isaIT = isaList.iterator();
while(isaIT.hasNext())
{
IsA isa = isaIT.next();
if(isa.getActor().getId()==deb.getId())
partSet.add(isa.getParticipant());
}
//special case for those commitments where debtor and creditor are the same actor
if (commitment.getPostCondition().getClass()== Trustworthiness.class)
{
if (partSet.size()==0)
{
//it means there is no mapping, so in the BP there are no such elements, simply delete the commitment
//and put in the undecidable
undecCommitmentList.add(commitment);
srs.getCommitmentList().remove(commitment);
}
else if (partSet.size()==1)
{
//setup the instantiated commitment
commitment.setDebtor(partSet.iterator().next());
commitment.setCreditor(commitment.getDebtor());//same creditor/debtor
}
else //more than one debtor
{
Iterator<Participant> debIT=partSet.iterator();
//i use the first debtor simply substituting the already existing commitment
commitment.setDebtor(debIT.next());
commitment.setCreditor(commitment.getDebtor());
//for all the other debtors i duplicate the commitment
//attention : i duplicate only the commitment object, not all the other objects referenced
while (debIT.hasNext())
{
Commitment newCommitment = new Commitment();
//set the other parameters as the old one
newCommitment.setPrecondition(commitment.getPrecondition());
newCommitment.setPostCondition(commitment.getPostCondition());
newCommitment.setId(commitment.getId());
//set the new debtor and creditor
newCommitment.setDebtor(debIT.next());
newCommitment.setCreditor(newCommitment.getDebtor());
//add the new commtments
srs.getCommitmentList().add(newCommitment);
}
}
}
//end of special case
else
{
//commented because it doesn't matter if the creditor is not instantiated, in other words is not present in the service composition
//if the set is composed by only one elements, i simply substituting, else i have to create new commitments
if (partSet.size()==0)
{
//it means there is no mapping, so in the BP there are no such elements,
//the responsible, i.e. the debtor must be istantiatedm, otherwise it means there is no mapped responsible in the bp,
//i.e. there is no participant who is in charge of sat the commitment
undecCommitmentList.add(commitment);
srs.getCommitmentList().remove(commitment);
//just set the creditor to null
//commitment.setDebtor(null);
}
else if (partSet.size()==1)
{
//setup the instantiated commitment
commitment.setDebtor(partSet.iterator().next());
}
else //more than one debtor
{
Iterator<Participant> debIT=partSet.iterator();
//i use the first debtor simply substituting the already existing commitment
commitment.setDebtor(debIT.next());
//for all the other debtors i duplicate the commitment
//attention : i duplicate only the commitment object, not all the other objects referenced
while (debIT.hasNext())
{
Commitment newCommiment = new Commitment();
//set the other parameters as the old one
newCommiment.setCreditor(commitment.getCreditor());
newCommiment.setPrecondition(commitment.getPrecondition());
newCommiment.setPostCondition(commitment.getPostCondition());
newCommiment.setId(commitment.getId());
//set the new debtor
newCommiment.setDebtor(debIT.next());
//add the new commitments
srs.getCommitmentList().add(newCommiment);
}
}
}
}
//once i instantiated all the debtor, i instantiate all the creditors
//since i have modified the commitment list during the first operations, i need to update the internal commitment list
commList = (Vector<Commitment>) srs.getCommitmentList().clone();
i = commList.iterator();
//for all commitments
while(i.hasNext())
{
Commitment commitment = i.next();
if (! (commitment.getPostCondition().getClass() == Trustworthiness.class))
{
//instantiate creditor
//clear old stuff
HashSet<Participant> partSet = new HashSet<Participant>();
Actor cred = commitment.getCreditor();
//if it's a role i have to search also in the plays relations
if (commitment.getCreditor().getClass()==Role.class)
{
Vector<Plays> playsList = mapping.getPlaysList();
Iterator<Plays> playsIT = playsList.iterator();
while (playsIT.hasNext())
{
Plays plays = playsIT.next();
if (plays.getActor().getId()==cred.getId())
partSet.add(plays.getParticipant());
}
}
Vector<IsA> isaList = mapping.getIsaList();
Iterator<IsA> isaIT = isaList.iterator();
while(isaIT.hasNext())
{
IsA isa = isaIT.next();
if(isa.getActor().getId()==cred.getId())
partSet.add(isa.getParticipant());
}
if (partSet.size()==0)
{
//it means there is no mapping of creditor, so in the BP there are no such elements, simply delete the commitment
//and put in the undecidable
//add the commitment to undec list only if is not in the list already
//if (!searchCommitment(commitment, undecCommitmentList))
// undecCommitmentList.add(commitment);
//srs.getCommitmentList().remove(commitment);
commitment.setCreditor(null);
}
//if the set is composed by only one elements, i simply substituting, else i have to create new commitments
else if (partSet.size()==1)
{
//setup the instantiated commitment
commitment.setCreditor(partSet.iterator().next());
}
else if (partSet.size()>=1)//more than one creditor
{
Iterator<Participant> debIT=partSet.iterator();
//i use the first creditor simply substituting the already existing commitment
commitment.setCreditor(debIT.next());
//for all the other creditor i duplicate the commitment
//attention : i duplicate only the commitment object, not all the other objects referenced
while (debIT.hasNext())
{
Commitment newCommitment = new Commitment();
//set the other parameters as the old one
newCommitment.setDebtor(commitment.getDebtor());
newCommitment.setPrecondition(commitment.getPrecondition());
newCommitment.setPostCondition(commitment.getPostCondition());
newCommitment.setId(commitment.getId());
//set the new creditor
newCommitment.setCreditor(debIT.next());
//add the new commitments
srs.getCommitmentList().add(newCommitment);
}
}
}
}
//once i instantiated all the creditor and all the debtors, i examine the post condition part
//since i have modified the commitment list during the first operations, i need to update the internal commitment list
//with this workaround i can update the original list of commitment while i'm iterating o the cloned one.
commList = (Vector<Commitment>) srs.getCommitmentList().clone();
i = commList.iterator();
//for all commitments
while(i.hasNext())
{
Commitment commitment = i.next();
//check the type of commitment and perform the respective instantiation
//pay attention to avoid to update the list because are only clones, if you want to update permanently the srs, do it through its object
if (commitment.getPostCondition().getClass()==NonRepudiation.class)
{
//non repudiation
NRInst.instantiateCommitment(commitment, mapping, srs, undecCommitmentList);
}
else if (commitment.getPostCondition().getClass()==NonDisclosure.class ||
commitment.getPostCondition().getClass()==NonModification.class ||
commitment.getPostCondition().getClass()==NonUsage.class ||
commitment.getPostCondition().getClass()==NonProduction.class)
{
OperationInst.instatiateCommitment(commitment, srs, mapping, undecCommitmentList);
}
else if (commitment.getPostCondition().getClass()==Trustworthiness.class)
{
TWInst.instantiateCommitment(commitment, mapping, srs, undecCommitmentList);
}
}
//instantiate the kb
//owners
Vector<Owns> ownsList = srs.getKnowledgeBase().getOwnsList();
Vector<Owns> newOwnsList = new Vector<Owns>();
Iterator<Owns> ownsListIT = ownsList.iterator();
while (ownsListIT.hasNext())
{
Owns owns = ownsListIT.next();
//maps the actors
HashSet<Participant> partSet = new HashSet<Participant>();
//if it's a role i have to search also in the plays relations
if (owns.getOwner().getClass()==Role.class)
{
Vector<Plays> playsList = mapping.getPlaysList();
Iterator<Plays> playsIT = playsList.iterator();
while (playsIT.hasNext())
{
Plays plays = playsIT.next();
if (plays.getActor().getId()==owns.getOwner().getId())
partSet.add(plays.getParticipant());
}
}
Vector<IsA> isaList = mapping.getIsaList();
Iterator<IsA> isaIT = isaList.iterator();
while(isaIT.hasNext())
{
IsA isa = isaIT.next();
if(isa.getActor().getId()==owns.getOwner().getId())
partSet.add(isa.getParticipant());
}
//maps the documents
HashSet<eu.aniketos.srcm.SRS.Document> DocuSet = new HashSet<eu.aniketos.srcm.SRS.Document>();
Information info = owns.getInformation();
//for all the document related to these info
Vector<TangibleBy> tangibleByList = srs.getKnowledgeBase().getTangibleByList();
Iterator<TangibleBy> tanByIT = tangibleByList.iterator();
while (tanByIT.hasNext())
{
TangibleBy tangibleBy = tanByIT.next();
if (tangibleBy.getInformation()==info)
{
DocuSet.add(tangibleBy.getDocument());
}
}
//set of variable associated at the set of document that made tangible the information of the non-disclosure
Vector<Variable> varList= new Vector<Variable>();
//once the possible documents set are filled, i search all the mapping in the mapping data structure
Iterator<eu.aniketos.srcm.SRS.Document> docuIT = DocuSet.iterator();
while (docuIT.hasNext())
{
eu.aniketos.srcm.SRS.Document doc= docuIT.next();
Vector<Represents> representsList = mapping.getRepresentsList();
Iterator<Represents> reprIT = representsList.iterator();
while(reprIT.hasNext())
{
Represents represents = reprIT.next();
if (represents.getDocument()==doc)
varList.add(represents.getVariable());
}
}
//at this point i have all the variable and all the owners of that variables
//i create the new owner relations
Iterator<Participant> partSetIT = partSet.iterator();
while (partSetIT.hasNext())
{
Participant owner = partSetIT.next();
@SuppressWarnings("rawtypes")
Iterator varListIT = varList.iterator();
while (varListIT.hasNext())
{
Owns ownsRel = new Owns();
ownsRel.setOwner(owner);
ownsRel.setInformation((Variable)varListIT.next());
newOwnsList.add(ownsRel);
}
}
}
//set the new list
srs.getKnowledgeBase().setOwnsList(newOwnsList);
//fully authorize relation instantiation
Vector<FullyAuthorized> faList = srs.getKnowledgeBase().getFullyAuthorizedList();
Vector<FullyAuthorized> newfaList = new Vector<FullyAuthorized>();
Iterator<FullyAuthorized> faListIT = faList.iterator();
while (faListIT.hasNext())
{
FullyAuthorized fa = faListIT.next();
//maps the actors
HashSet<Participant> partSet = new HashSet<Participant>();
//if it's a role i have to search also in the plays relations
if (fa.getOwner().getClass()==Role.class)
{
Vector<Plays> playsList = mapping.getPlaysList();
Iterator<Plays> playsIT = playsList.iterator();
while (playsIT.hasNext())
{
Plays plays = playsIT.next();
if (plays.getActor().getId()==fa.getOwner().getId())
partSet.add(plays.getParticipant());
}
}
Vector<IsA> isaList = mapping.getIsaList();
Iterator<IsA> isaIT = isaList.iterator();
while(isaIT.hasNext())
{
IsA isa = isaIT.next();
if(isa.getActor().getId()==fa.getOwner().getId())
partSet.add(isa.getParticipant());
}
//maps the documents
HashSet<eu.aniketos.srcm.SRS.Document> DocuSet = new HashSet<eu.aniketos.srcm.SRS.Document>();
Information info = fa.getInformation();
//for all the document related to these info
Vector<TangibleBy> tangibleByList = srs.getKnowledgeBase().getTangibleByList();
Iterator<TangibleBy> tanByIT = tangibleByList.iterator();
while (tanByIT.hasNext())
{
TangibleBy tangibleBy = tanByIT.next();
if (tangibleBy.getInformation()==info)
{
DocuSet.add(tangibleBy.getDocument());
}
}
//set of variable associated at the set of document that made tangible the information of the non-disclosure
Vector<Variable> varList= new Vector<Variable>();
//once the possible documents set are filled, i search all the mapping in the mapping data structure
Iterator<eu.aniketos.srcm.SRS.Document> docuIT = DocuSet.iterator();
while (docuIT.hasNext())
{
eu.aniketos.srcm.SRS.Document doc= docuIT.next();
Vector<Represents> representsList = mapping.getRepresentsList();
Iterator<Represents> reprIT = representsList.iterator();
while(reprIT.hasNext())
{
Represents represents = reprIT.next();
if (represents.getDocument()==doc)
varList.add(represents.getVariable());
}
}
//at this point i have all the variable and all the owners of that variables
//i create the new fully auth relations
Iterator<Participant> partSetIT = partSet.iterator();
while (partSetIT.hasNext())
{
Participant fullyAuthorized = partSetIT.next();
Iterator varListIT = varList.iterator();
while (varListIT.hasNext())
{
FullyAuthorized faRel = new FullyAuthorized();
faRel.setOwner(fullyAuthorized);
faRel.setInformation((Variable)varListIT.next());
newfaList.add(faRel);
}
}
}
//set the new list
srs.getKnowledgeBase().setFullyAuthorizedList(newfaList);
}
//it return true if the commitment is contained in the list of commitment
private Boolean searchCommitment (Commitment commitment, HashSet<Commitment> commitmentList)
{
Iterator<Commitment> commListIT = commitmentList.iterator();
while (commListIT.hasNext())
{
Commitment commExtracted= commListIT.next();
if (commitment.getId().compareTo(commExtracted.getId())==0)
return true;
}
return false;
}
}