Added Share Template
git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/tabular-data-gwt-service@100772 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
7185351ccc
commit
78182ecb33
|
@ -24,7 +24,8 @@ import org.gcube.portlets.user.td.gwtservice.shared.monitor.OperationMonitor;
|
|||
import org.gcube.portlets.user.td.gwtservice.shared.monitor.OperationMonitorSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.sdmx.SDMXExportSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.sdmx.SDMXImportSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareInfo;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareTabResource;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareTemplate;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.source.SDMXRegistrySource;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.task.TaskResubmitSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.task.TaskResumeSession;
|
||||
|
@ -96,6 +97,14 @@ public interface TDGWTService extends RemoteService {
|
|||
* @throws TDGWTServiceException
|
||||
*/
|
||||
public UserInfo hello() throws TDGWTServiceException;
|
||||
|
||||
/**
|
||||
* Restore UI session
|
||||
*
|
||||
* @return
|
||||
* @throws TDGWTServiceException
|
||||
*/
|
||||
public TRId restoreUISession() throws TDGWTServiceException;
|
||||
|
||||
// TabularResource
|
||||
/**
|
||||
|
@ -339,23 +348,25 @@ public interface TDGWTService extends RemoteService {
|
|||
|
||||
// Share
|
||||
/**
|
||||
* Retrieves information sharing on the tabular resource
|
||||
*
|
||||
* @param trId
|
||||
* @return
|
||||
* @throws TDGWTServiceException
|
||||
*/
|
||||
//public ShareInfo getShareInfo(TRId trId) throws TDGWTServiceException;
|
||||
|
||||
/**
|
||||
* Share sabular resource
|
||||
* Share tabular resource
|
||||
*
|
||||
* @param shareInfo
|
||||
* @return
|
||||
* @throws TDGWTServiceException
|
||||
*/
|
||||
public void setShare(ShareInfo shareInfo) throws TDGWTServiceException;
|
||||
public void setShare(ShareTabResource shareInfo) throws TDGWTServiceException;
|
||||
|
||||
/**
|
||||
* Share template
|
||||
*
|
||||
* @param shareTemplate
|
||||
* @return
|
||||
* @throws TDGWTServiceException
|
||||
*/
|
||||
public void setShareTemplate(ShareTemplate shareTemplate) throws TDGWTServiceException;
|
||||
|
||||
|
||||
|
||||
// Open
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,8 @@ import org.gcube.portlets.user.td.gwtservice.shared.monitor.OperationMonitor;
|
|||
import org.gcube.portlets.user.td.gwtservice.shared.monitor.OperationMonitorSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.sdmx.SDMXExportSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.sdmx.SDMXImportSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareInfo;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareTabResource;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareTemplate;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.source.SDMXRegistrySource;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.task.TaskResubmitSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.task.TaskResumeSession;
|
||||
|
@ -82,6 +83,8 @@ public interface TDGWTServiceAsync {
|
|||
|
||||
void hello(AsyncCallback<UserInfo> callback);
|
||||
|
||||
void restoreUISession(AsyncCallback<TRId> callback);
|
||||
|
||||
// TabularResource
|
||||
void getCurrentTRId(AsyncCallback<TRId> callback);
|
||||
|
||||
|
@ -168,10 +171,11 @@ public interface TDGWTServiceAsync {
|
|||
void startDiscard(TRId trId, AsyncCallback<String> callback);
|
||||
|
||||
// Share
|
||||
//void getShareInfo(TRId trId, AsyncCallback<ShareInfo> callback);
|
||||
|
||||
void setShare(ShareInfo shareInfo, AsyncCallback<Void> callback);
|
||||
|
||||
void setShare(ShareTabResource shareInfo, AsyncCallback<Void> callback);
|
||||
|
||||
void setShareTemplate(ShareTemplate shareTemplate,AsyncCallback<Void> callback);
|
||||
|
||||
|
||||
// CodelistPagingLoaded
|
||||
void setCodelistsPagingLoader(AsyncCallback<Void> callback);
|
||||
|
||||
|
|
|
@ -171,7 +171,8 @@ import org.gcube.portlets.user.td.gwtservice.shared.monitor.OperationMonitorSess
|
|||
import org.gcube.portlets.user.td.gwtservice.shared.sdmx.SDMXExportSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.sdmx.SDMXImportSession;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.Contacts;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareInfo;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareTabResource;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.ShareTemplate;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.source.SDMXRegistrySource;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.source.SourceType;
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.task.InvocationS;
|
||||
|
@ -289,6 +290,44 @@ public class TDGWTServiceImpl extends RemoteServiceServlet implements
|
|||
return userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TRId restoreUISession() throws TDGWTServiceException {
|
||||
try {
|
||||
HttpSession session = this.getThreadLocalRequest().getSession();
|
||||
SessionUtil.getAslSession(session);
|
||||
|
||||
TRId trId = SessionUtil.getTRId(session);
|
||||
logger.debug("restoreUISession()");
|
||||
if (trId == null) {
|
||||
logger.error("No UI Session");
|
||||
throw new TDGWTServiceException("UI session is null");
|
||||
} else {
|
||||
logger.debug("Restore UI Session():" + trId);
|
||||
SessionUtil.removeAllFromCurrentTabularResourcesOpen(session);
|
||||
TabResource tabResource = SessionUtil.getTabResource(session);
|
||||
SessionUtil.addToCurrentTabularResourcesOpen(session,
|
||||
tabResource);
|
||||
}
|
||||
return trId;
|
||||
|
||||
} catch (TDGWTServiceException e) {
|
||||
throw e;
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
throw new TDGWTServiceException(
|
||||
"Security exception, you haven't rights!");
|
||||
} catch (Throwable e) {
|
||||
logger.error("restoreUISession(): " + e.getLocalizedMessage(), e);
|
||||
throw new TDGWTServiceException("Error in UI Session Restore: "
|
||||
+ e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritDoc}
|
||||
|
@ -575,7 +614,7 @@ public class TDGWTServiceImpl extends RemoteServiceServlet implements
|
|||
Contacts owner = new Contacts("", tr.getOwner(), false);
|
||||
currentTR.setOwner(owner);
|
||||
currentTR.setContacts(retrieveShareInfo(tr));
|
||||
|
||||
|
||||
SessionUtil.setTabResource(session, currentTR);
|
||||
logger.debug("GetTabResourceInformation() updated information:"
|
||||
+ currentTR.toString());
|
||||
|
@ -637,7 +676,7 @@ public class TDGWTServiceImpl extends RemoteServiceServlet implements
|
|||
Contacts owner = new Contacts("", tr.getOwner(), false);
|
||||
currentTR.setOwner(owner);
|
||||
currentTR.setContacts(retrieveShareInfo(tr));
|
||||
|
||||
|
||||
logger.debug("GetTabResourceInformation() updated information:"
|
||||
+ currentTR);
|
||||
return currentTR;
|
||||
|
@ -4808,7 +4847,7 @@ public class TDGWTServiceImpl extends RemoteServiceServlet implements
|
|||
}
|
||||
}
|
||||
|
||||
List<String> sharedWithGroups = tr.getSharedWithGroup();
|
||||
List<String> sharedWithGroups = tr.getSharedWithGroups();
|
||||
logger.debug("Shared with Groups: " + sharedWithUsers);
|
||||
if (sharedWithGroups != null) {
|
||||
for (String group : sharedWithGroups) {
|
||||
|
@ -4834,62 +4873,48 @@ public class TDGWTServiceImpl extends RemoteServiceServlet implements
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
/*
|
||||
@Override
|
||||
public ShareInfo getShareInfo(TRId trId) throws TDGWTServiceException {
|
||||
try {
|
||||
HttpSession session = this.getThreadLocalRequest().getSession();
|
||||
ASLSession aslSession = SessionUtil.getAslSession(session);
|
||||
|
||||
TabResource tabResource = getTabResourceInformation(trId);
|
||||
|
||||
AuthorizationProvider.instance.set(new AuthorizationToken(
|
||||
aslSession.getUsername(), aslSession.getScope()));
|
||||
TabularDataService service = TabularDataServiceFactory.getService();
|
||||
|
||||
TabularResourceId serviceTR = new TabularResourceId(
|
||||
Long.valueOf(tabResource.getTrId().getId()));
|
||||
|
||||
TabularResource tr = service.getTabularResource(serviceTR);
|
||||
ArrayList<Contacts> contacts = new ArrayList<Contacts>();
|
||||
List<String> sharedWithUsers = tr.getSharedWithUsers();
|
||||
logger.debug("Shared with Users: " + sharedWithUsers);
|
||||
if (sharedWithUsers != null) {
|
||||
for (String user : sharedWithUsers) {
|
||||
Contacts cont = new Contacts(user, user, false);
|
||||
contacts.add(cont);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> sharedWithGroups = tr.getSharedWithGroup();
|
||||
logger.debug("Shared with Groups: " + sharedWithUsers);
|
||||
if (sharedWithGroups != null) {
|
||||
for (String group : sharedWithGroups) {
|
||||
Contacts cont = new Contacts(group, group, true);
|
||||
contacts.add(cont);
|
||||
}
|
||||
}
|
||||
|
||||
ShareInfo shareInfo = new ShareInfo(tabResource, contacts);
|
||||
return shareInfo;
|
||||
} catch (TDGWTServiceException e) {
|
||||
throw e;
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
throw new TDGWTServiceException(
|
||||
"Security exception, you haven't rights!");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new TDGWTServiceException("Error in getShareInfo: "
|
||||
+ e.getLocalizedMessage());
|
||||
}
|
||||
}*/
|
||||
* @Override public ShareInfo getShareInfo(TRId trId) throws
|
||||
* TDGWTServiceException { try { HttpSession session =
|
||||
* this.getThreadLocalRequest().getSession(); ASLSession aslSession =
|
||||
* SessionUtil.getAslSession(session);
|
||||
*
|
||||
* TabResource tabResource = getTabResourceInformation(trId);
|
||||
*
|
||||
* AuthorizationProvider.instance.set(new AuthorizationToken(
|
||||
* aslSession.getUsername(), aslSession.getScope())); TabularDataService
|
||||
* service = TabularDataServiceFactory.getService();
|
||||
*
|
||||
* TabularResourceId serviceTR = new TabularResourceId(
|
||||
* Long.valueOf(tabResource.getTrId().getId()));
|
||||
*
|
||||
* TabularResource tr = service.getTabularResource(serviceTR);
|
||||
* ArrayList<Contacts> contacts = new ArrayList<Contacts>(); List<String>
|
||||
* sharedWithUsers = tr.getSharedWithUsers();
|
||||
* logger.debug("Shared with Users: " + sharedWithUsers); if
|
||||
* (sharedWithUsers != null) { for (String user : sharedWithUsers) {
|
||||
* Contacts cont = new Contacts(user, user, false); contacts.add(cont); } }
|
||||
*
|
||||
* List<String> sharedWithGroups = tr.getSharedWithGroup();
|
||||
* logger.debug("Shared with Groups: " + sharedWithUsers); if
|
||||
* (sharedWithGroups != null) { for (String group : sharedWithGroups) {
|
||||
* Contacts cont = new Contacts(group, group, true); contacts.add(cont); } }
|
||||
*
|
||||
* ShareInfo shareInfo = new ShareInfo(tabResource, contacts); return
|
||||
* shareInfo; } catch (TDGWTServiceException e) { throw e; } catch
|
||||
* (SecurityException e) { e.printStackTrace(); throw new
|
||||
* TDGWTServiceException( "Security exception, you haven't rights!"); }
|
||||
* catch (Throwable e) { e.printStackTrace(); throw new
|
||||
* TDGWTServiceException("Error in getShareInfo: " +
|
||||
* e.getLocalizedMessage()); } }
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setShare(ShareInfo shareInfo) throws TDGWTServiceException {
|
||||
public void setShare(ShareTabResource shareInfo)
|
||||
throws TDGWTServiceException {
|
||||
try {
|
||||
HttpSession session = this.getThreadLocalRequest().getSession();
|
||||
ASLSession aslSession = SessionUtil.getAslSession(session);
|
||||
|
@ -4929,6 +4954,52 @@ public class TDGWTServiceImpl extends RemoteServiceServlet implements
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setShareTemplate(ShareTemplate shareTemplate)
|
||||
throws TDGWTServiceException {
|
||||
try {
|
||||
HttpSession session = this.getThreadLocalRequest().getSession();
|
||||
ASLSession aslSession = SessionUtil.getAslSession(session);
|
||||
logger.debug("ShareTemplate: " + shareTemplate);
|
||||
AuthorizationProvider.instance.set(new AuthorizationToken(
|
||||
aslSession.getUsername(), aslSession.getScope()));
|
||||
TabularDataService service = TabularDataServiceFactory.getService();
|
||||
|
||||
TemplateId templateId = new TemplateId(Long.valueOf(shareTemplate
|
||||
.getTemplateData().getId()));
|
||||
|
||||
List<AuthorizationToken> users = new ArrayList<AuthorizationToken>();
|
||||
for (Contacts cont : shareTemplate.getContacts()) {
|
||||
AuthorizationToken at;
|
||||
if (cont.isGroup()) {
|
||||
at = new AuthorizationToken(null, cont.getLogin());
|
||||
} else {
|
||||
at = new AuthorizationToken(cont.getLogin());
|
||||
}
|
||||
users.add(at);
|
||||
}
|
||||
AuthorizationToken[] usersArray = users
|
||||
.toArray(new AuthorizationToken[0]);
|
||||
|
||||
logger.debug("Share with Users: " + users);
|
||||
service.share(templateId, usersArray);
|
||||
|
||||
} catch (TDGWTServiceException e) {
|
||||
throw e;
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
throw new TDGWTServiceException(
|
||||
"Security exception, you haven't rights!");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new TDGWTServiceException("Error on service");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkTabularResourceNotFinal(TRId trId)
|
||||
throws TDGWTServiceException {
|
||||
try {
|
||||
|
@ -5158,8 +5229,10 @@ public class TDGWTServiceImpl extends RemoteServiceServlet implements
|
|||
break;
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
Contacts owner = new Contacts("", desc.getOwner(), false);
|
||||
templateData.setOwner(owner);
|
||||
templateData.setContacts(retrieveTemplateShareInfo(desc));
|
||||
templateDataList.add(templateData);
|
||||
}
|
||||
logger.debug("Retrieved TemplateData List");
|
||||
|
@ -5182,6 +5255,44 @@ public class TDGWTServiceImpl extends RemoteServiceServlet implements
|
|||
|
||||
}
|
||||
|
||||
protected ArrayList<Contacts> retrieveTemplateShareInfo(
|
||||
TemplateDescription templateDescription)
|
||||
throws TDGWTServiceException {
|
||||
try {
|
||||
|
||||
ArrayList<Contacts> contacts = new ArrayList<Contacts>();
|
||||
List<String> sharedWithUsers = templateDescription
|
||||
.getSharedWithUsers();
|
||||
logger.debug("Shared with Users: " + sharedWithUsers);
|
||||
if (sharedWithUsers != null) {
|
||||
for (String user : sharedWithUsers) {
|
||||
Contacts cont = new Contacts(user, user, false);
|
||||
contacts.add(cont);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> sharedWithGroups = templateDescription
|
||||
.getSharedWithGroups();
|
||||
logger.debug("Shared with Groups: " + sharedWithUsers);
|
||||
if (sharedWithGroups != null) {
|
||||
for (String group : sharedWithGroups) {
|
||||
Contacts cont = new Contacts(group, group, true);
|
||||
contacts.add(cont);
|
||||
}
|
||||
}
|
||||
return contacts;
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace();
|
||||
throw new TDGWTServiceException(
|
||||
"Security exception, you haven't rights!");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new TDGWTServiceException("Error in retrieveShareInfo: "
|
||||
+ e.getLocalizedMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* {@inheritDoc}
|
||||
|
|
|
@ -6,18 +6,18 @@ import java.util.ArrayList;
|
|||
import org.gcube.portlets.user.td.gwtservice.shared.tr.TabResource;
|
||||
|
||||
|
||||
public class ShareInfo implements Serializable {
|
||||
public class ShareTabResource implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4803711252511329006L;
|
||||
|
||||
protected TabResource tabResource;
|
||||
protected ArrayList<Contacts> contacts;
|
||||
|
||||
public ShareInfo() {
|
||||
public ShareTabResource() {
|
||||
|
||||
}
|
||||
|
||||
public ShareInfo(TabResource tabResource, ArrayList<Contacts> contacts) {
|
||||
public ShareTabResource(TabResource tabResource, ArrayList<Contacts> contacts) {
|
||||
this.tabResource = tabResource;
|
||||
this.contacts = contacts;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package org.gcube.portlets.user.td.gwtservice.shared.share;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.template.TemplateData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author giancarlo
|
||||
* email: <a href="mailto:g.panichi@isti.cnr.it">g.panichi@isti.cnr.it</a>
|
||||
*
|
||||
*/
|
||||
public class ShareTemplate implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1860135253322944179L;
|
||||
|
||||
protected TemplateData templateData;
|
||||
protected ArrayList<Contacts> contacts;
|
||||
|
||||
public ShareTemplate() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ShareTemplate(TemplateData templateData, ArrayList<Contacts> contacts) {
|
||||
super();
|
||||
this.templateData = templateData;
|
||||
this.contacts = contacts;
|
||||
}
|
||||
|
||||
public TemplateData getTemplateData() {
|
||||
return templateData;
|
||||
}
|
||||
|
||||
public void setTemplateData(TemplateData templateData) {
|
||||
this.templateData = templateData;
|
||||
}
|
||||
|
||||
public ArrayList<Contacts> getContacts() {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public void setContacts(ArrayList<Contacts> contacts) {
|
||||
this.contacts = contacts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ShareTemplate [templateData=" + templateData + ", contacts="
|
||||
+ contacts + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
package org.gcube.portlets.user.td.gwtservice.shared.template;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.gcube.portlets.user.td.gwtservice.shared.share.Contacts;
|
||||
|
||||
/**
|
||||
* Template Description
|
||||
|
@ -18,8 +21,37 @@ public class TemplateData implements Serializable {
|
|||
private String description;
|
||||
private String agency;
|
||||
private String category;
|
||||
protected Contacts owner;
|
||||
protected ArrayList<Contacts> contacts;
|
||||
|
||||
|
||||
public TemplateData(){
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id
|
||||
* @param name
|
||||
* @param description
|
||||
* @param agency
|
||||
* @param category
|
||||
* @param owner
|
||||
* @param contacts
|
||||
*/
|
||||
public TemplateData(long id, String name, String description,
|
||||
String agency, String category, Contacts owner,
|
||||
ArrayList<Contacts> contacts) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.agency = agency;
|
||||
this.category = category;
|
||||
this.owner = owner;
|
||||
this.contacts = contacts;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -60,16 +92,42 @@ public class TemplateData implements Serializable {
|
|||
this.category = category;
|
||||
}
|
||||
|
||||
public Contacts getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(Contacts owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getOwnerLogin() {
|
||||
String login = null;
|
||||
if (owner != null) {
|
||||
login = owner.getLogin();
|
||||
}
|
||||
return login;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<Contacts> getContacts() {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public void setContacts(ArrayList<Contacts> contacts) {
|
||||
this.contacts = contacts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TemplateData [id=" + id + ", name=" + name + ", description="
|
||||
+ description + ", agency=" + agency + ", category=" + category
|
||||
+ "]";
|
||||
+ ", owner=" + owner + ", contacts=" + contacts + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue