branch feature/7017 updated (d34cd1e -> f3e984a)
This is an automated email from the git hooks/post-receive script. New change to branch feature/7017 in repository observe. See http://git.codelutin.com/observe.git from d34cd1e refactor save action for table entities new f3e984a debut d'implantation pour les ecrans de type tableau (refs #7017) The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit f3e984a7fe19bcf0853d529382f53e1f9c434f2a Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Apr 29 08:49:43 2015 +0200 debut d'implantation pour les ecrans de type tableau (refs #7017) Summary of changes: .../fr/ird/observe/services/EntityAssociation.java | 39 +++++++ .../data/seine/ObjectObservedSpeciesService.java | 34 ++++++ .../data/seine/ObjectSchoolEstimateService.java | 34 ++++++ ...eineService.java => SchoolEstimateService.java} | 28 +++-- .../data/seine/SchoolEstimateServiceImpl.java | 120 +++++++++++++++++++++ .../ui/content/table/ContentTableUIHandler.java | 57 +++++++--- .../impl/seine/ObjectObservedSpeciesUIHandler.java | 22 +++- .../impl/seine/ObjectSchoolEstimateUIHandler.java | 27 +++-- .../table/impl/seine/SchoolEstimateUIHandler.java | 22 ++-- 9 files changed, 336 insertions(+), 47 deletions(-) create mode 100644 observe-services/src/main/java/fr/ird/observe/services/EntityAssociation.java create mode 100644 observe-services/src/main/java/fr/ird/observe/services/data/seine/ObjectObservedSpeciesService.java create mode 100644 observe-services/src/main/java/fr/ird/observe/services/data/seine/ObjectSchoolEstimateService.java copy observe-services/src/main/java/fr/ird/observe/services/data/seine/{SetSeineService.java => SchoolEstimateService.java} (50%) create mode 100644 observe-services/src/main/java/fr/ird/observe/services/data/seine/SchoolEstimateServiceImpl.java -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@list.forge.codelutin.com>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/7017 in repository observe. See http://git.codelutin.com/observe.git commit f3e984a7fe19bcf0853d529382f53e1f9c434f2a Author: Tony CHEMIT <chemit@codelutin.com> Date: Wed Apr 29 08:49:43 2015 +0200 debut d'implantation pour les ecrans de type tableau (refs #7017) --- .../fr/ird/observe/services/EntityAssociation.java | 39 +++++++ .../data/seine/ObjectObservedSpeciesService.java | 34 ++++++ .../data/seine/ObjectSchoolEstimateService.java | 34 ++++++ .../services/data/seine/SchoolEstimateService.java | 36 +++++++ .../data/seine/SchoolEstimateServiceImpl.java | 120 +++++++++++++++++++++ .../ui/content/table/ContentTableUIHandler.java | 57 +++++++--- .../impl/seine/ObjectObservedSpeciesUIHandler.java | 22 +++- .../impl/seine/ObjectSchoolEstimateUIHandler.java | 27 +++-- .../table/impl/seine/SchoolEstimateUIHandler.java | 22 ++-- 9 files changed, 359 insertions(+), 32 deletions(-) diff --git a/observe-services/src/main/java/fr/ird/observe/services/EntityAssociation.java b/observe-services/src/main/java/fr/ird/observe/services/EntityAssociation.java new file mode 100644 index 0000000..bac1fa9 --- /dev/null +++ b/observe-services/src/main/java/fr/ird/observe/services/EntityAssociation.java @@ -0,0 +1,39 @@ +package fr.ird.observe.services; + +import org.nuiton.topia.persistence.TopiaEntity; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * Represents an entity with one of his association. + * + * Created on 4/28/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class EntityAssociation<P extends TopiaEntity, C extends TopiaEntity> { + + protected final P parentEntity; + + protected final Collection<C> childEntities; + + public EntityAssociation(P parentEntity) { + this.parentEntity = parentEntity; + this.childEntities = new ArrayList<C>(); + } + + public P getParentEntity() { + return parentEntity; + } + + public Collection<C> getChildEntities() { + return childEntities; + } + + public void addChildEntity(C entity) { + childEntities.add(entity); + } + +} diff --git a/observe-services/src/main/java/fr/ird/observe/services/data/seine/ObjectObservedSpeciesService.java b/observe-services/src/main/java/fr/ird/observe/services/data/seine/ObjectObservedSpeciesService.java new file mode 100644 index 0000000..4d50592 --- /dev/null +++ b/observe-services/src/main/java/fr/ird/observe/services/data/seine/ObjectObservedSpeciesService.java @@ -0,0 +1,34 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.entities.seine.FloatingObject; +import fr.ird.observe.entities.seine.ObjectObservedSpecies; +import fr.ird.observe.services.Commit; +import fr.ird.observe.services.NoTransaction; +import fr.ird.observe.services.ObserveService; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +/** + * Created on 4/28/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public interface ObjectObservedSpeciesService extends ObserveService { + + FloatingObject loadForEdit(String floatingObjectId); + + @Commit + void save(FloatingObject floatingObject); + + @NoTransaction + TopiaEntityBinder<FloatingObject> getBinderForFloatingObjectEdit(); + + @NoTransaction + void copyForEdit(FloatingObject source, FloatingObject target); + + @NoTransaction + TopiaEntityBinder<ObjectObservedSpecies> getBinderForObjectObservedSpeciesEdit(); + + @NoTransaction + void copyForEdit(ObjectObservedSpecies source, ObjectObservedSpecies target); +} \ No newline at end of file diff --git a/observe-services/src/main/java/fr/ird/observe/services/data/seine/ObjectSchoolEstimateService.java b/observe-services/src/main/java/fr/ird/observe/services/data/seine/ObjectSchoolEstimateService.java new file mode 100644 index 0000000..afc6127 --- /dev/null +++ b/observe-services/src/main/java/fr/ird/observe/services/data/seine/ObjectSchoolEstimateService.java @@ -0,0 +1,34 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.entities.seine.FloatingObject; +import fr.ird.observe.entities.seine.ObjectSchoolEstimate; +import fr.ird.observe.services.Commit; +import fr.ird.observe.services.NoTransaction; +import fr.ird.observe.services.ObserveService; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +/** + * Created on 4/28/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public interface ObjectSchoolEstimateService extends ObserveService { + + FloatingObject loadForEdit(String floatingObjectId); + + @Commit + void save(FloatingObject floatingObject); + + @NoTransaction + TopiaEntityBinder<FloatingObject> getBinderForFloatingObjectEdit(); + + @NoTransaction + void copyForEdit(FloatingObject source, FloatingObject target); + + @NoTransaction + TopiaEntityBinder<ObjectSchoolEstimate> getBinderForObjectSchoolEstimateEdit(); + + @NoTransaction + void copyForEdit(ObjectSchoolEstimate source, ObjectSchoolEstimate target); +} diff --git a/observe-services/src/main/java/fr/ird/observe/services/data/seine/SchoolEstimateService.java b/observe-services/src/main/java/fr/ird/observe/services/data/seine/SchoolEstimateService.java new file mode 100644 index 0000000..ce72a1b --- /dev/null +++ b/observe-services/src/main/java/fr/ird/observe/services/data/seine/SchoolEstimateService.java @@ -0,0 +1,36 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.entities.seine.SchoolEstimate; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.services.Commit; +import fr.ird.observe.services.EntityAssociation; +import fr.ird.observe.services.NoTransaction; +import fr.ird.observe.services.ObserveService; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +/** + * Created on 4/28/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public interface SchoolEstimateService extends ObserveService { + + SetSeine loadForEdit(String setSeineId); + + @Commit + void save(EntityAssociation<SetSeine, SchoolEstimate> setSeine); + + @NoTransaction + TopiaEntityBinder<SetSeine> getBinderForSetSeineEdit(); + + @NoTransaction + void copyForEdit(SetSeine source, SetSeine target); + + @NoTransaction + TopiaEntityBinder<SchoolEstimate> getBinderForSchoolEstimateEdit(); + + @NoTransaction + void copyForEdit(SchoolEstimate source, SchoolEstimate target); + +} diff --git a/observe-services/src/main/java/fr/ird/observe/services/data/seine/SchoolEstimateServiceImpl.java b/observe-services/src/main/java/fr/ird/observe/services/data/seine/SchoolEstimateServiceImpl.java new file mode 100644 index 0000000..fa2da33 --- /dev/null +++ b/observe-services/src/main/java/fr/ird/observe/services/data/seine/SchoolEstimateServiceImpl.java @@ -0,0 +1,120 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.seine.SchoolEstimate; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.services.AbstractObserveService; +import fr.ird.observe.services.EntityAssociation; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; +import org.nuiton.util.beans.BinderModelBuilder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created on 4/28/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class SchoolEstimateServiceImpl extends AbstractObserveService implements SchoolEstimateService { + + @Override + public SetSeine loadForEdit(String setSeineId) { + + SetSeine parentToLoad = findByTopiaId(SetSeine.class, setSeineId); + + SetSeine parentLoaded = getDao(SetSeine.class).newInstance(); + copyForEdit(parentToLoad, parentLoaded); + + if (!parentToLoad.isSchoolEstimateEmpty()) { + + TopiaDAO<SchoolEstimate> childDao = getDao(SchoolEstimate.class); + + List<SchoolEstimate> childs = new ArrayList<SchoolEstimate>(); + + for (SchoolEstimate sourceChild : parentToLoad.getSchoolEstimate()) { + + SchoolEstimate targetChild = childDao.newInstance(); + copyForEdit(sourceChild, targetChild); + childs.add(targetChild); + + } + + parentLoaded.setSchoolEstimate(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(EntityAssociation<SetSeine, SchoolEstimate> setSeine) { + + } + + @Override + public TopiaEntityBinder<SetSeine> getBinderForSetSeineEdit() { + + + TopiaEntityBinder<SetSeine> binder = loadBinder("-forSchoolEstimateEdit", SetSeine.class, new CreateBinder<SetSeine>() { + + @Override + public BinderModelBuilder<SetSeine, SetSeine> createBinderBuilder(BinderService binderService, String name) { + + BinderModelBuilder<SetSeine, SetSeine> builder = binderService.newBinderBuilder( + SetSeine.class, + SetSeine.PROPERTY_COMMENT, SetSeine.PROPERTY_SCHOOL_ESTIMATE); + + return builder; + + } + + }); + + return binder; + + } + + @Override + public void copyForEdit(SetSeine source, SetSeine target) { + + getBinderForSetSeineEdit().load(source, target, true); + + } + + @Override + public TopiaEntityBinder<SchoolEstimate> getBinderForSchoolEstimateEdit() { + + TopiaEntityBinder<SchoolEstimate> binder = loadBinder("-forEdit", SchoolEstimate.class, new CreateBinder<SchoolEstimate>() { + + @Override + public BinderModelBuilder<SchoolEstimate, SchoolEstimate> createBinderBuilder(BinderService binderService, String name) { + + BinderModelBuilder<SchoolEstimate, SchoolEstimate> builder = binderService.newBinderBuilder( + SchoolEstimate.class, + SchoolEstimate.PROPERTY_SET_SEINE, + SchoolEstimate.PROPERTY_SPECIES, + SchoolEstimate.PROPERTY_TOTAL_WEIGHT, + SchoolEstimate.PROPERTY_MEAN_WEIGHT); + + return builder; + + } + + }); + + return binder; + + } + + @Override + public void copyForEdit(SchoolEstimate source, SchoolEstimate target) { + + getBinderForSchoolEstimateEdit().load(source, target, true); + + } + +} diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/ContentTableUIHandler.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/ContentTableUIHandler.java index 76e2783..bd2bb30 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/ContentTableUIHandler.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/ContentTableUIHandler.java @@ -193,34 +193,53 @@ public abstract class ContentTableUIHandler<E extends TopiaEntity, D extends Top protected abstract void initTableUI(DefaultTableCellRenderer renderer); - protected abstract String getEditBeanIdToLoad(DataContext dataContext, + protected String getEditBeanIdToLoad(DataContext dataContext, DataService dataService, - DataSource dataSource) throws DataSourceException; + DataSource dataSource) throws DataSourceException { + throw new IllegalStateException("Do NOT USE ME!!!"); + } protected E loadEditBean(ContentMode mode, DataContext dataContext, DataService dataService, DataSource dataSource) throws DataSourceException { - String id = getEditBeanIdToLoad(dataContext, dataService, dataSource); + loadEditBean(); - if (id == null) { - throw new IllegalStateException("Could not find id form " + this); - } +// String id = getEditBeanIdToLoad(dataContext, dataService, dataSource); +// +// if (id == null) { +// throw new IllegalStateException("Could not find id form " + this); +// } +// +// // preparation du bean d'édition +// dataService.loadEditEntity(dataSource, id, getLoadExecutor()); + +// getModel().setMode(mode); +// +// // initialisation du modèle du tableau +// getUi().getTableModel().attachModel(); E editBean = getBean(); + return editBean; - // preparation du bean d'édition - dataService.loadEditEntity(dataSource, id, getLoadExecutor()); + } - getModel().setMode(mode); + //FIXME Rendre cette methode abstract + protected void loadEditBean() throws DataSourceException { - // initialisation du modèle du tableau - getUi().getTableModel().attachModel(); + String id = getEditBeanIdToLoad(getDataContext(), getDataService(), getDataSource()); + + if (id == null) { + throw new IllegalStateException("Could not find id form " + this); + } + + // preparation du bean d'édition + getDataService().loadEditEntity(getDataSource(), id, getLoadExecutor()); - return editBean; } + //FIXME A supprimer @Override protected final void onLoad(TopiaContext tx, E bean) throws TopiaException { super.onLoad(tx, bean); @@ -234,6 +253,7 @@ public abstract class ContentTableUIHandler<E extends TopiaEntity, D extends Top getModel().getChildsUpdator().setChilds(editBean, data); } + //FIXME A supprimer protected Collection<D> loadChilds(TopiaContext tx, E bean) throws TopiaException { Collection<D> childs = getModel().getChildsUpdator().getChilds(bean); Collection<D> data = new ArrayList<D>(); @@ -290,6 +310,10 @@ public abstract class ContentTableUIHandler<E extends TopiaEntity, D extends Top Species2.newSpeciesByIdPredicate(speciesIds)); } + protected void loadTableEditBeanForm(ContentMode mode) { + // par defaut, rien à faire + } + @Override public void openUI() throws Exception { @@ -307,6 +331,15 @@ public abstract class ContentTableUIHandler<E extends TopiaEntity, D extends Top // chargement du bean d'édition loadEditBean(mode, getDataContext(), getDataService(), getDataSource()); + // chargement de l'écran d'édition + loadTableEditBeanForm(mode); + + // enregistrement du mode de l'écran + getModel().setMode(mode); + + // initialisation du modèle du tableau + getUi().getTableModel().attachModel(); + boolean canEdit = mode == ContentMode.UPDATE; if (canEdit) { diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/ObjectObservedSpeciesUIHandler.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/ObjectObservedSpeciesUIHandler.java index 9bbbd05..e1e7460 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/ObjectObservedSpeciesUIHandler.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/ObjectObservedSpeciesUIHandler.java @@ -21,15 +21,14 @@ */ package fr.ird.observe.ui.content.table.impl.seine; -import fr.ird.observe.DataService; import fr.ird.observe.ObserveConfig; -import fr.ird.observe.db.DataContext; -import fr.ird.observe.db.DataSource; +import fr.ird.observe.db.DataSourceException; import fr.ird.observe.db.constants.DataContextType; import fr.ird.observe.entities.referentiel.Species; import fr.ird.observe.entities.referentiel.seine.SpeciesStatus; import fr.ird.observe.entities.seine.FloatingObject; import fr.ird.observe.entities.seine.ObjectObservedSpecies; +import fr.ird.observe.services.data.seine.ObjectObservedSpeciesService; import fr.ird.observe.ui.UIHelper; import fr.ird.observe.ui.content.table.ContentTableUIHandler; import org.apache.commons.logging.Log; @@ -60,10 +59,23 @@ public class ObjectObservedSpeciesUIHandler extends ContentTableUIHandler<Floati } @Override - protected String getEditBeanIdToLoad(DataContext dataContext, DataService dataService, DataSource dataSource) { - return dataContext.getSelectedFloatingObjectId(); + protected void loadEditBean() throws DataSourceException { + + String floatingObjectId = getDataContext().getSelectedFloatingObjectId(); + + ObjectObservedSpeciesService service = getService(ObjectObservedSpeciesService.class); + + FloatingObject loaded = service.loadForEdit(floatingObjectId); + + service.copyForEdit(loaded, getBean()); + } +// @Override +// protected String getEditBeanIdToLoad(DataContext dataContext, DataService dataService, DataSource dataSource) { +// return dataContext.getSelectedFloatingObjectId(); +// } + @Override protected void onSelectedRowChanged(int editingRow, ObjectObservedSpecies bean, boolean create) { if (log.isDebugEnabled()) { diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/ObjectSchoolEstimateUIHandler.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/ObjectSchoolEstimateUIHandler.java index 4823b5e..542486d 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/ObjectSchoolEstimateUIHandler.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/ObjectSchoolEstimateUIHandler.java @@ -21,14 +21,13 @@ */ package fr.ird.observe.ui.content.table.impl.seine; -import fr.ird.observe.DataService; import fr.ird.observe.ObserveConfig; -import fr.ird.observe.db.DataContext; -import fr.ird.observe.db.DataSource; +import fr.ird.observe.db.DataSourceException; import fr.ird.observe.db.constants.DataContextType; import fr.ird.observe.entities.referentiel.Species; import fr.ird.observe.entities.seine.FloatingObject; import fr.ird.observe.entities.seine.ObjectSchoolEstimate; +import fr.ird.observe.services.data.seine.ObjectSchoolEstimateService; import fr.ird.observe.ui.UIHelper; import fr.ird.observe.ui.content.table.ContentTableUIHandler; import org.apache.commons.logging.Log; @@ -58,6 +57,20 @@ public class ObjectSchoolEstimateUIHandler extends ContentTableUIHandler<Floatin return (ObjectSchoolEstimateUI) super.getUi(); } + + @Override + protected void loadEditBean() throws DataSourceException { + + String floatingObjectId = getDataContext().getSelectedFloatingObjectId(); + + ObjectSchoolEstimateService service = getService(ObjectSchoolEstimateService.class); + + FloatingObject loaded = service.loadForEdit(floatingObjectId); + + service.copyForEdit(loaded, getBean()); + + } + @Override protected void onSelectedRowChanged(int editingRow, ObjectSchoolEstimate bean, boolean create) { if (getTableModel().isEditable()) { @@ -68,10 +81,10 @@ public class ObjectSchoolEstimateUIHandler extends ContentTableUIHandler<Floatin } } - @Override - protected String getEditBeanIdToLoad(DataContext dataContext, DataService dataService, DataSource dataSource) { - return dataContext.getSelectedFloatingObjectId(); - } +// @Override +// protected String getEditBeanIdToLoad(DataContext dataContext, DataService dataService, DataSource dataSource) { +// return dataContext.getSelectedFloatingObjectId(); +// } @Override protected void initTableUI(DefaultTableCellRenderer renderer) { diff --git a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/SchoolEstimateUIHandler.java b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/SchoolEstimateUIHandler.java index 4cc82df..43a449c 100644 --- a/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/SchoolEstimateUIHandler.java +++ b/observe-swing/src/main/java/fr/ird/observe/ui/content/table/impl/seine/SchoolEstimateUIHandler.java @@ -21,10 +21,7 @@ */ package fr.ird.observe.ui.content.table.impl.seine; -import fr.ird.observe.DataService; import fr.ird.observe.ObserveConfig; -import fr.ird.observe.db.DataContext; -import fr.ird.observe.db.DataSource; import fr.ird.observe.db.DataSourceException; import fr.ird.observe.db.constants.DataContextType; import fr.ird.observe.entities.referentiel.Ocean; @@ -34,6 +31,7 @@ import fr.ird.observe.entities.referentiel.Species2; import fr.ird.observe.entities.seine.SchoolEstimate; import fr.ird.observe.entities.seine.SetSeine; import fr.ird.observe.services.data.TripService; +import fr.ird.observe.services.data.seine.SchoolEstimateService; import fr.ird.observe.services.referential.ReferentialService; import fr.ird.observe.ui.UIHelper; import fr.ird.observe.ui.content.ContentMode; @@ -74,19 +72,27 @@ public class SchoolEstimateUIHandler extends ContentTableUIHandler<SetSeine, Sch } @Override - protected String getEditBeanIdToLoad(DataContext dataContext, DataService dataService, DataSource dataSource) { - return dataContext.getSelectedSetId(); + protected void loadEditBean() throws DataSourceException { + + String setSeineId = getDataContext().getSelectedSetId(); + + SchoolEstimateService service = getService(SchoolEstimateService.class); + + SetSeine loaded = service.loadForEdit(setSeineId); + + service.copyForEdit(loaded, getBean()); + } @Override - protected SetSeine loadEditBean(ContentMode mode, DataContext dataContext, DataService dataService, DataSource dataSource) throws DataSourceException { + protected void loadTableEditBeanForm(ContentMode mode) { List<Species> speciesList; if (mode == ContentMode.UPDATE) { // get current ocean - Ocean ocean = getService(TripService.class).getTripOcean(dataContext.getSelectedTripId()); + Ocean ocean = getService(TripService.class).getTripOcean(getDataContext().getSelectedTripId()); // get all species from the configured speciesList ObserveConfig config = getUi().getContextValue(ObserveConfig.class); @@ -109,7 +115,7 @@ public class SchoolEstimateUIHandler extends ContentTableUIHandler<SetSeine, Sch if (log.isDebugEnabled()) { log.debug("speciesList = " + speciesList.size()); } - return super.loadEditBean(mode, dataContext, dataService, dataSource); + } @Override -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@list.forge.codelutin.com>.
participants (1)
-
codelutin.com scm