*/\r
package eu.etaxonomy.taxeditor.editor.name.handler;\r
\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+import java.util.UUID;\r
+\r
+import org.apache.log4j.Logger;\r
import org.eclipse.core.commands.AbstractHandler;\r
import org.eclipse.core.commands.ExecutionEvent;\r
import org.eclipse.core.commands.ExecutionException;\r
import org.eclipse.core.commands.IHandler;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
import org.eclipse.jface.viewers.ISelection;\r
import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.ui.IEditorPart;\r
import org.eclipse.ui.PartInitException;\r
import org.eclipse.ui.handlers.HandlerUtil;\r
\r
+import eu.etaxonomy.cdm.api.conversation.ConversationHolder;\r
+import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
+import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
+import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;\r
+import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
import eu.etaxonomy.cdm.model.taxon.Taxon;\r
import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
import eu.etaxonomy.taxeditor.editor.EditorUtil;\r
-import eu.etaxonomy.taxeditor.editor.Page;\r
-import eu.etaxonomy.taxeditor.editor.name.TaxonNameEditor;\r
import eu.etaxonomy.taxeditor.propertysheet.name.TaxonBasePropertySource;\r
+import eu.etaxonomy.taxeditor.store.CdmStore;\r
\r
/**\r
* @author p.ciardelli\r
*/\r
public class ChangeAcceptedTaxonToSynonymHandler extends AbstractHandler\r
implements IHandler {\r
+ private static final Logger logger = Logger\r
+ .getLogger(ChangeAcceptedTaxonToSynonymHandler.class);\r
\r
/* (non-Javadoc)\r
* @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)\r
// "Not yet implemented", \r
// "'Change Accepted Taxon to Synonym' not yet implemented.");\r
\r
- TaxonNameEditor editor = (TaxonNameEditor) EditorUtil.getActiveEditorPage(\r
- Page.NAME);\r
ISelection menuSelection = HandlerUtil.getActiveMenuSelection(event);\r
- \r
- \r
- \r
TaxonBasePropertySource taxonBasePropertySource = \r
(TaxonBasePropertySource) ((StructuredSelection) menuSelection).getFirstElement();\r
- Taxon taxon = (Taxon) taxonBasePropertySource.getTaxonBase();\r
- \r
- Taxon newAcceptedTaxon = FilteredTaxonSelectionDialog.getTaxon(HandlerUtil.getActiveShell(event), taxon);\r
-// TaxonNameBase newTaxonName = FilteredNameSelectionDialog.getName(HandlerUtil.getActiveShell(event), taxon.getName());\r
+ Taxon oldAcceptedTaxon = (Taxon) taxonBasePropertySource.getTaxonBase();\r
\r
+ // Choose new accepted taxon\r
+ Taxon newAcceptedTaxon = FilteredTaxonSelectionDialog.getTaxon(HandlerUtil.getActiveShell(event), oldAcceptedTaxon);\r
+ \r
+ if (newAcceptedTaxon == null) {\r
+ return null;\r
+ }\r
\r
-// IEditorInput input = TaxonEditorInput.NewInstance(newAcceptedTaxon.getUuid()); \r
try {\r
- TaxonNode taxonNode = newAcceptedTaxon.getTaxonNodes().iterator().next();\r
- EditorUtil.open(taxonNode.getUuid());\r
+ ConversationHolder conversation = CdmStore.NewTransactionalConversation();\r
+ conversation.bind();\r
+ Taxon newTaxon = (Taxon) CdmStore.getTaxonService().getTaxonByUuid(newAcceptedTaxon.getUuid());\r
+ Taxon oldTaxon = (Taxon) CdmStore.getTaxonService().getTaxonByUuid(oldAcceptedTaxon.getUuid());\r
+ \r
+ // Check for multiple nodes\r
+ if (newTaxon.getTaxonNodes().size() > 1 || oldTaxon.getTaxonNodes().size() > 1) {\r
+ MessageDialog.openInformation(HandlerUtil.getActiveShell(event), \r
+ "Taxon implemented in multiple trees", \r
+ "One or both of these taxa is implemented in multiple taxonomic trees.");\r
+ return null;\r
+ }\r
+ \r
+ // Close editor\r
+ IEditorPart editor = HandlerUtil.getActiveEditor(event);\r
+ boolean proceed = HandlerUtil.getActiveWorkbenchWindowChecked(event).getActivePage().\r
+ closeEditor(editor, true);\r
+ if (!proceed) {\r
+ return null;\r
+ }\r
+ \r
+ makeTaxonSynonym(oldTaxon, newTaxon, null, null, null);\r
+ \r
+ // TEMP\r
+// Set<TaxonDescription> descriptions = new HashSet<TaxonDescription>();\r
+// for(TaxonDescription taxDescription : oldTaxon.getDescriptions()){\r
+// descriptions.add(taxDescription);\r
+// } \r
+// for(TaxonDescription taxDescription : descriptions){\r
+// newTaxon.addDescription(taxDescription);\r
+// } \r
+ \r
+// CdmStore.getTaxonService().makeTaxonSynonym(oldTaxon, newTaxon, null, null, null);\r
+ conversation.commit();\r
+ Set<TaxonNode> nodes = newTaxon.getTaxonNodes();\r
+ UUID uuid = nodes.iterator().next().getUuid();\r
+ \r
+ EditorUtil.open(uuid);\r
+ \r
} catch (PartInitException e) {\r
// TODO Auto-generated catch block\r
e.printStackTrace();\r
\r
return null;\r
}\r
+\r
+ /**\r
+ * @param oldTaxon\r
+ * @param newTaxon\r
+ */\r
+ private void makeTaxonSynonym(Taxon oldTaxon, Taxon newAcceptedTaxon, SynonymRelationshipType synonymType, ReferenceBase citation, String citationMicroReference) {\r
+ if (oldTaxon == null || newAcceptedTaxon == null || oldTaxon.getName() == null){\r
+ return;\r
+ }\r
+ \r
+ // Move oldTaxon to newTaxon\r
+ TaxonNameBase<?,?> synonymName = oldTaxon.getName();\r
+ if (synonymType == null){\r
+ if (synonymName.isHomotypic(newAcceptedTaxon.getName())){\r
+ synonymType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();\r
+ }else{\r
+ //TODO synonymType \r
+ synonymType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();\r
+ }\r
+ }\r
+ SynonymRelationship synRel = newAcceptedTaxon.addSynonymName(synonymName, synonymType, citation, citationMicroReference);\r
+ \r
+ //Move Synonym Relations to new Taxon\r
+ for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){\r
+ synRelation.setAcceptedTaxon(newAcceptedTaxon);\r
+// newAcceptedTaxon.addSynonym(synRelation.getSynonym(), synRelation.getType(), \r
+// synRelation.getCitation(), synRelation.getCitationMicroReference());\r
+ }\r
+\r
+ //Move Taxon RelationShips to new Taxon\r
+ Set<TaxonRelationship> removableTaxonRels = new HashSet<TaxonRelationship>();\r
+ for(TaxonRelationship taxonRelation : oldTaxon.getTaxonRelations()){\r
+ //CHILDREN\r
+ if (taxonRelation.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){\r
+ if (taxonRelation.getFromTaxon() == oldTaxon){\r
+ taxonRelation.setFromTaxon(newAcceptedTaxon);\r
+// removableTaxonRels.add(taxonRelation);\r
+ }else if(taxonRelation.getToTaxon() == oldTaxon){\r
+ taxonRelation.setToTaxon(newAcceptedTaxon);\r
+// newAcceptedTaxon.addTaxonomicChild(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
+// removableTaxonRels.add(taxonRelation);\r
+ }else{\r
+ logger.warn("Taxon is not part of its own Taxonrelationship");\r
+ }\r
+ }\r
+ //MISAPPLIED NAMES\r
+ if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){\r
+ if (taxonRelation.getFromTaxon() == oldTaxon){\r
+ taxonRelation.setFromTaxon(newAcceptedTaxon);\r
+// newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
+// removableTaxonRels.add(taxonRelation);\r
+ }else if(taxonRelation.getToTaxon() == oldTaxon){\r
+ taxonRelation.setToTaxon(newAcceptedTaxon);\r
+// newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
+// removableTaxonRels.add(taxonRelation);\r
+ }else{\r
+ logger.warn("Taxon is not part of its own Taxonrelationship");\r
+ }\r
+ }\r
+ //Concept Relationships\r
+ //FIXME implement\r
+ }\r
+ \r
+// for(TaxonRelationship taxonRel : removableTaxonRels) {\r
+// oldTaxon.removeTaxonRelation(taxonRel);\r
+// }\r
+ \r
+ //Move Descriptions to new Taxon\r
+ Set<TaxonDescription> descriptions = new HashSet<TaxonDescription>();\r
+ for(TaxonDescription taxDescription : oldTaxon.getDescriptions()){\r
+ descriptions.add(taxDescription);\r
+ } \r
+ for(TaxonDescription taxDescription : descriptions){\r
+ newAcceptedTaxon.addDescription(taxDescription);\r
+ }\r
+ \r
+ CdmStore.getTaxonService().saveTaxon(newAcceptedTaxon);\r
+ oldTaxon.getTaxonNodes().iterator().next().remove();\r
+ CdmStore.getTaxonService().removeTaxon(oldTaxon);\r
+ }\r
+ \r
+// /**\r
+// * @param oldTaxon\r
+// * @param newTaxon\r
+// */\r
+// private void makeTaxonSynonym(Taxon oldTaxon, Taxon newAcceptedTaxon, SynonymRelationshipType synonymType, ReferenceBase citation, String citationMicroReference) {\r
+// if (oldTaxon == null || newAcceptedTaxon == null || oldTaxon.getName() == null){\r
+// return;\r
+// }\r
+// \r
+// // Move oldTaxon to newTaxon\r
+// TaxonNameBase<?,?> synonymName = oldTaxon.getName();\r
+// if (synonymType == null){\r
+// if (synonymName.isHomotypic(newAcceptedTaxon.getName())){\r
+// synonymType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();\r
+// }else{\r
+// //TODO synonymType \r
+// synonymType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();\r
+// }\r
+// }\r
+// SynonymRelationship synRel = newAcceptedTaxon.addSynonymName(synonymName, synonymType, citation, citationMicroReference);\r
+// \r
+// //Move Synonym Relations to new Taxon\r
+// for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){\r
+// newAcceptedTaxon.addSynonym(synRelation.getSynonym(), synRelation.getType(), \r
+// synRelation.getCitation(), synRelation.getCitationMicroReference());\r
+// }\r
+//\r
+// //Move Taxon RelationShips to new Taxon\r
+// Set<TaxonRelationship> removableTaxonRels = new HashSet<TaxonRelationship>();\r
+// for(TaxonRelationship taxonRelation : oldTaxon.getTaxonRelations()){\r
+// //CHILDREN\r
+// if (taxonRelation.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){\r
+// if (taxonRelation.getFromTaxon() == oldTaxon){\r
+// removableTaxonRels.add(taxonRelation);\r
+//// oldTaxon.removeTaxonRelation(taxonRelation);\r
+// }else if(taxonRelation.getToTaxon() == oldTaxon){\r
+// newAcceptedTaxon.addTaxonomicChild(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
+// removableTaxonRels.add(taxonRelation);\r
+//// oldTaxon.removeTaxonRelation(taxonRelation);\r
+// }else{\r
+// logger.warn("Taxon is not part of its own Taxonrelationship");\r
+// }\r
+// }\r
+// //MISAPPLIED NAMES\r
+// if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){\r
+// if (taxonRelation.getFromTaxon() == oldTaxon){\r
+// newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
+// removableTaxonRels.add(taxonRelation);\r
+//// oldTaxon.removeTaxonRelation(taxonRelation);\r
+// }else if(taxonRelation.getToTaxon() == oldTaxon){\r
+// newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
+// removableTaxonRels.add(taxonRelation);\r
+//// oldTaxon.removeTaxonRelation(taxonRelation);\r
+// }else{\r
+// logger.warn("Taxon is not part of its own Taxonrelationship");\r
+// }\r
+// }\r
+// //Concept Relationships\r
+// //FIXME implement\r
+//// if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIEDNAMEFOR())){\r
+//// if (taxonRelation.getFromTaxon() == oldTaxon){\r
+//// newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
+//// removableTaxonRels.add(taxonRelation);\r
+//// }else if(taxonRelation.getToTaxon() == oldTaxon){\r
+//// newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());\r
+//// removableTaxonRels.add(taxonRelation);\r
+//// }else{\r
+//// logger.warn("Taxon is not part of its own Taxonrelationship");\r
+//// }\r
+//// }\r
+// }\r
+// \r
+// for(TaxonRelationship taxonRel : removableTaxonRels) {\r
+// oldTaxon.removeTaxonRelation(taxonRel);\r
+// }\r
+// \r
+// //Move Descriptions to new Taxon\r
+// Set<TaxonDescription> descriptions = new HashSet<TaxonDescription>();\r
+// for(TaxonDescription taxDescription : oldTaxon.getDescriptions()){\r
+// descriptions.add(taxDescription);\r
+// } \r
+// for(TaxonDescription taxDescription : descriptions){\r
+// newAcceptedTaxon.addDescription(taxDescription);\r
+// }\r
+// \r
+// CdmStore.getTaxonService().saveTaxon(newAcceptedTaxon);\r
+//// CdmStore.getTaxonService().removeTaxon(oldTaxon);\r
+// }\r
}
\ No newline at end of file
*/\r
package eu.etaxonomy.taxeditor.editor.name.handler;\r
\r
-import java.util.List;\r
+import java.text.Collator;\r
+import java.util.Comparator;\r
+import java.util.Map;\r
+import java.util.UUID;\r
\r
import org.apache.log4j.Logger;\r
import org.eclipse.core.runtime.CoreException;\r
import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.jface.dialogs.IDialogSettings;\r
+import org.eclipse.jface.viewers.ILabelProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
import org.eclipse.jface.window.Window;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;\r
\r
-import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
import eu.etaxonomy.cdm.model.taxon.Taxon;\r
-import eu.etaxonomy.taxeditor.dialogs.FilteredCdmResourceSelectionDialog;\r
import eu.etaxonomy.taxeditor.store.CdmStore;\r
+import eu.etaxonomy.taxeditor.store.internal.TaxeditorStorePlugin;\r
\r
/**\r
* @author p.ciardelli\r
*\r
*/\r
-public class FilteredTaxonSelectionDialog extends FilteredCdmResourceSelectionDialog {\r
+//public class FilteredTaxonSelectionDialog extends FilteredCdmResourceSelectionDialog {\r
+/**\r
+ * @author p.ciardelli\r
+ *\r
+ */\r
+public class FilteredTaxonSelectionDialog extends FilteredItemsSelectionDialog { \r
+ \r
private static final Logger logger = Logger\r
.getLogger(FilteredTaxonSelectionDialog.class);\r
\r
+ public static final String SETTINGS = FilteredTaxonSelectionDialog.class.getCanonicalName();\r
+ \r
/**\r
* @param taxon\r
* @return\r
*/\r
public static Taxon getTaxon(Shell shell, Taxon excludeTaxon) {\r
FilteredTaxonSelectionDialog dialog = new FilteredTaxonSelectionDialog(shell, \r
- "Choose a taxon");\r
+ "Choose a taxon", false);\r
if (dialog.open() == Window.CANCEL) {\r
return null;\r
}\r
}\r
\r
private Taxon taxon;\r
+ private Map<UUID, String> allTaxonBases;\r
\r
/**\r
* @param shell\r
* @param title\r
*/\r
- public FilteredTaxonSelectionDialog(Shell shell, String title) {\r
- super(shell, title);\r
- setMessage("Choose your shit here, bro");\r
- }\r
- \r
- /* (non-Javadoc)\r
- * @see eu.etaxonomy.taxeditor.dialogs.FilteredCdmResourceSelectionDialog#getSettings()\r
- */\r
- @Override\r
- public String getSettings() {\r
- // TODO Auto-generated method stub\r
- return null;\r
+ public FilteredTaxonSelectionDialog(Shell shell, String title, boolean multi) {\r
+ super(shell, multi);\r
+ setTitle(title);\r
+ setMessage("Choose");\r
+ \r
+ ILabelProvider labelProvider = new LabelProvider() {\r
+ public String getText(Object element) {\r
+ if (element == null) {\r
+ return null;\r
+ }\r
+ return ((TaxonUuidAndTitleCache) element).getTitleCache();\r
+ } \r
+ };\r
+ setListLabelProvider(labelProvider);\r
+ setDetailsLabelProvider(labelProvider);\r
+ \r
+ allTaxonBases = CdmStore.getTaxonService().getUuidAndTitleCacheOfAcceptedTaxa();\r
}\r
\r
/* (non-Javadoc)\r
protected void fillContentProvider(AbstractContentProvider contentProvider,\r
ItemsFilter itemsFilter, IProgressMonitor progressMonitor)\r
throws CoreException {\r
- progressMonitor.beginTask("Looking for taxa", 1000);\r
- List allTaxonBases = CdmStore.searchTaxaByName("*"+itemsFilter.getPattern()+"*");\r
- for (Object obj : allTaxonBases){\r
- if (obj instanceof Taxon) {\r
- contentProvider.add((Taxon) obj, itemsFilter);\r
- }\r
- progressMonitor.worked(1);\r
+ progressMonitor.beginTask("Looking for taxa", 1000); // Why no progres monitor?\r
+ for (UUID uuid : allTaxonBases.keySet()) {\r
+ TaxonUuidAndTitleCache taxon = new TaxonUuidAndTitleCache(uuid, allTaxonBases.get(uuid)); \r
+ contentProvider.add(taxon, itemsFilter);\r
}\r
}\r
\r
Object[] result = getResult();\r
return result[0] == null ? null : (Taxon) result[0];\r
}\r
+\r
+ /* (non-Javadoc)\r
+ * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createExtendedContentArea(org.eclipse.swt.widgets.Composite)\r
+ */\r
+ @Override\r
+ protected Control createExtendedContentArea(Composite parent) {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#createFilter()\r
+ */\r
+ @Override\r
+ protected ItemsFilter createFilter() {\r
+ return new ItemsFilter() {\r
+\r
+ @Override\r
+ public boolean isConsistentItem(Object item) {\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public boolean matchItem(Object item) {\r
+ return matches(((TaxonUuidAndTitleCache) item).titleCache);\r
+ }\r
+ \r
+ };\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getDialogSettings()\r
+ */\r
+ @Override\r
+ protected IDialogSettings getDialogSettings() {\r
+ IDialogSettings settings = TaxeditorStorePlugin.getDefault().getDialogSettings().getSection(getSettings());\r
+\r
+ if (settings == null) {\r
+ settings = TaxeditorStorePlugin.getDefault().getDialogSettings().addNewSection(getSettings());\r
+ }\r
+ return settings;\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getElementName(java.lang.Object)\r
+ */\r
+ @Override\r
+ public String getElementName(Object item) {\r
+ return ((TaxonUuidAndTitleCache) item).getTitleCache();\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#getItemsComparator()\r
+ */\r
+ @Override\r
+ protected Comparator getItemsComparator() {\r
+ return new Comparator<TaxonUuidAndTitleCache>() {\r
+ public int compare(TaxonUuidAndTitleCache entity1,\r
+ TaxonUuidAndTitleCache entity2) {\r
+ Collator collator = Collator.getInstance();\r
+ return collator.compare(entity1.getTitleCache(), entity2.getTitleCache());\r
+ }\r
+ };\r
+ }\r
+\r
+ /* (non-Javadoc)\r
+ * @see org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#validateItem(java.lang.Object)\r
+ */\r
+ @Override\r
+ protected IStatus validateItem(Object item) {\r
+ return Status.OK_STATUS;\r
+ }\r
+ \r
+ protected void restoreDialog(IDialogSettings settings) {\r
+ \r
+ }\r
+ \r
+ public String getSettings() {\r
+ if(SETTINGS == null){\r
+ throw new IllegalStateException("No SETTINGS set.");\r
+ }\r
+ return SETTINGS;\r
+ }\r
+ \r
+ class TaxonUuidAndTitleCache {\r
+\r
+ UUID uuid;\r
+ String titleCache;\r
+ \r
+ TaxonUuidAndTitleCache(UUID uuid, String titleCache) {\r
+ this.uuid = uuid;\r
+ this.titleCache = titleCache;\r
+ }\r
+ \r
+ /**\r
+ * @return the titleCache\r
+ */\r
+ public String getTitleCache() {\r
+ return titleCache;\r
+ }\r
+ \r
+ /**\r
+ * @return the uuid\r
+ */\r
+ public UUID getUuid() {\r
+ return uuid;\r
+ }\r
+ }\r
}
\ No newline at end of file