r256 - in trunk/jredmine-client/src/main/java/org/nuiton/jredmine: . request
Author: tchemit Date: 2012-03-25 17:37:26 +0200 (Sun, 25 Mar 2012) New Revision: 256 Url: http://nuiton.org/repositories/revision/jredmine/256 Log: refs #2030 introduce request package for redmine request builder (wno more use of the helper-m-p api) Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/DefaultRedmineRequestBuilder.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/IssueScopeRedmineRequestBuilder.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/ProjectScopeRedmineRequestBuilder.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequest.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestBuilder.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestFactory.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/VersionScopeRedmineRequestBuilder.java Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/DefaultRedmineRequestBuilder.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/DefaultRedmineRequestBuilder.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/DefaultRedmineRequestBuilder.java 2012-03-25 15:37:26 UTC (rev 256) @@ -0,0 +1,107 @@ +/* + * #%L + * JRedmine :: Client + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.jredmine.request; + +import org.apache.commons.lang.ArrayUtils; + +import java.io.File; +import java.util.Map; + +/** + * The default implementation of the redmine request builder. + * + * @author tchemit <chemit@codelutin.com> + * @see RedmineRequestBuilder + * @see RedmineRequest + * @since 1.4 + */ +public class DefaultRedmineRequestBuilder implements RedmineRequestBuilder { + + private static final long serialVersionUID = 1L; + + protected final String name; + + protected final String action; + + public DefaultRedmineRequestBuilder(String action) { + this(action, action); + } + + public DefaultRedmineRequestBuilder(String name, String action) { + this.name = name; + this.action = action; + } + + @Override + public String getName() { + return name; + } + + /** + * Compute a array of pair (key-value) from the given arguments. + * <p/> + * Order is important to do this, define it. + * + * @param args the args of the request + * @return parameters to use in request by pari of key-value + * (key,value,key2, value2) + */ + public String[] getParameters(Object... args) { + // by default, no parameter + return ArrayUtils.EMPTY_STRING_ARRAY; + } + + public String[] getPath(Object... args) { + // by default, path is action + return new String[]{action}; + } + + public Map<String, File> getAttachments(Object... args) { + // by default, no attachments + return null; + } + + @Override + public RedmineRequest create(final Object... args) { + + return new RedmineRequest() { + + @Override + public String[] getPath() { + return DefaultRedmineRequestBuilder.this.getPath(args); + } + + @Override + public String[] getParameters() { + return DefaultRedmineRequestBuilder.this.getParameters(args); + } + + @Override + public Map<String, File> getAttachments() { + return DefaultRedmineRequestBuilder.this.getAttachments(args); + } + }; + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/DefaultRedmineRequestBuilder.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/IssueScopeRedmineRequestBuilder.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/IssueScopeRedmineRequestBuilder.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/IssueScopeRedmineRequestBuilder.java 2012-03-25 15:37:26 UTC (rev 256) @@ -0,0 +1,57 @@ +/* + * #%L + * JRedmine :: Client + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.jredmine.request; + +/** + * To build request with a project and issue scope. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4 + */ +public class IssueScopeRedmineRequestBuilder extends ProjectScopeRedmineRequestBuilder { + + private static final long serialVersionUID = 1L; + + public IssueScopeRedmineRequestBuilder(String name, String action) { + super(name, action); + } + + public IssueScopeRedmineRequestBuilder(String action) { + super(action); + } + + @Override + public String[] getParameters(Object... args) { + + // args 1 = project id + // args 2 = issue id + + String issueId = (String) args[1]; + + return new String[]{ + "issue_id", issueId + }; + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/IssueScopeRedmineRequestBuilder.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/ProjectScopeRedmineRequestBuilder.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/ProjectScopeRedmineRequestBuilder.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/ProjectScopeRedmineRequestBuilder.java 2012-03-25 15:37:26 UTC (rev 256) @@ -0,0 +1,57 @@ +/* + * #%L + * JRedmine :: Client + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.jredmine.request; + +/** + * To build request with a project scope. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4 + */ +public class ProjectScopeRedmineRequestBuilder extends DefaultRedmineRequestBuilder { + + private static final long serialVersionUID = 1L; + + public ProjectScopeRedmineRequestBuilder(String name, String action) { + super(name, action); + } + + public ProjectScopeRedmineRequestBuilder(String action) { + super(action); + } + + @Override + public String[] getPath(Object... args) { + + // one args : projectName + + String projectName = (String) args[0]; + + return new String[]{ + action, + projectName + }; + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/ProjectScopeRedmineRequestBuilder.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequest.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequest.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequest.java 2012-03-25 15:37:26 UTC (rev 256) @@ -0,0 +1,49 @@ +/* + * #%L + * JRedmine :: Client + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.jredmine.request; + +import java.io.File; +import java.util.Map; + +/** + * To define a redmine request. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4 + */ +public interface RedmineRequest { + + /** @return the splitted path to add to url */ + String[] getPath(); + + /** + * @return an array of pair (parameter name - parameter value) to pass + * to request + */ + String[] getParameters(); + + /** @return the map of attachment to pass to request */ + Map<String, File> getAttachments(); +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestBuilder.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestBuilder.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestBuilder.java 2012-03-25 15:37:26 UTC (rev 256) @@ -0,0 +1,47 @@ +/* + * #%L + * JRedmine :: Client + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.jredmine.request; + +import java.io.Serializable; + +/** + * The contract of a redmine request builder. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4 + */ +public interface RedmineRequestBuilder extends Serializable { + + /** @return the unique name of the request builder */ + String getName(); + + /** + * Create the request given the {@code args}. + * + * @param args args to create the request + * @return the created request + */ + RedmineRequest create(Object... args); +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestBuilder.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestFactory.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestFactory.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestFactory.java 2012-03-25 15:37:26 UTC (rev 256) @@ -0,0 +1,292 @@ +/* + * #%L + * JRedmine :: Client + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.jredmine.request; + +import com.google.common.base.Strings; +import com.google.common.collect.Maps; +import org.nuiton.jredmine.model.Attachment; +import org.nuiton.jredmine.model.News; +import org.nuiton.jredmine.model.TimeEntry; +import org.nuiton.jredmine.model.Version; +import org.nuiton.jredmine.model.VersionStatusEnum; + +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * Factory of {@link RedmineRequest}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4 + */ +public class RedmineRequestFactory { + + public static final DateFormat DATE_FORMAT = + new SimpleDateFormat("yyyy-MM-dd"); + + /** registred requests */ + protected final Map<String, RedmineRequestBuilder> requestBuilders; + + public RedmineRequestFactory() { + requestBuilders = Maps.newTreeMap(); + } + + public void addDefaultRequests() { + for (DEFAULT_REQUESTS request : DEFAULT_REQUESTS.values()) { + addRequestBuilder(request.requestBuilder); + } + } + + /** + * Add a request into the factory. + * + * @param builder the new request to add + */ + public void addRequestBuilder(RedmineRequestBuilder builder) { + String name = builder.getName(); + if (requestBuilders.containsKey(name)) { + throw new IllegalArgumentException("a request builder with name " + + name + " already exists."); + } + requestBuilders.put(name, builder); + } + + /** + * Obtain a request given his id and the args given. + * + * @param id id of the request + * @param args args passed to build the request + * @return the new request + */ + public RedmineRequest getRequest(String id, Object... args) { + + RedmineRequest r; + RedmineRequestBuilder builder = requestBuilders.get(id); + if (builder == null) { + + throw new IllegalArgumentException( + "Could not find any request builder for request named '" + + id + "'"); + } + r = builder.create(args); + if (r == null) { + throw new IllegalArgumentException( + "Could not find any request named '" + id + + "' using builder " + builder); + } + return r; + } + + public enum DEFAULT_REQUESTS { + + // misc requests + + PING(new DefaultRedmineRequestBuilder("ping")), + LOGOUT(new DefaultRedmineRequestBuilder("logout")), + LOGIN(new DefaultRedmineRequestBuilder("login") { + private static final long serialVersionUID = 1L; + + @Override + public String[] getParameters(Object... args) { + String login = (String) args[0]; + String password = (String) args[1]; + return new String[]{"username", login, "password", password}; + } + }), + + // with no scope + + GET_PROJECT_LIST(new DefaultRedmineRequestBuilder("get_projects.xml")), + GET_USER_PROJECTS(new DefaultRedmineRequestBuilder("get_user_projects.xml")), + GET_ISSUE_STATUS_LIST(new DefaultRedmineRequestBuilder("get_issue_statuses.xml")), + GET_ISSUE_PRIORITY_LIST(new DefaultRedmineRequestBuilder("get_issue_priorities.xml")), + + // with project scope + + GET_PROJECT(new ProjectScopeRedmineRequestBuilder("get_project.xml")), + GET_PROJECT_ISSUES(new ProjectScopeRedmineRequestBuilder("get_project_issues.xml")), + GET_PROJECT_OPENED_ISSUES(new ProjectScopeRedmineRequestBuilder("get_project_opened_issues.xml")), + GET_PROJECT_CLOSED_ISSUES(new ProjectScopeRedmineRequestBuilder("get_project_closed_issues.xml")), + GET_VERSION_LIST(new ProjectScopeRedmineRequestBuilder("get_project_versions.xml")), + GET_ISSUE_CATEGORY_LIST(new ProjectScopeRedmineRequestBuilder("get_issue_categories.xml")), + GET_TRACKER_LIST(new ProjectScopeRedmineRequestBuilder("get_project_trackers.xml")), + GET_USER_LIST(new ProjectScopeRedmineRequestBuilder("get_project_users.xml")), + GET_NEWS_LIST(new ProjectScopeRedmineRequestBuilder("get_project_news.xml")), + + ADD_VERSION(new ProjectScopeRedmineRequestBuilder("add_version.xml") { + private static final long serialVersionUID = 1L; + + @Override + public String[] getParameters(Object... args) { + Version version = (Version) args[1]; + String date = getVersionEffectiveDate(version); + String status = getVersionStatus(version); + return new String[]{ + "version[name]", version.getName(), + "version[description]", version.getDescription(), + "version[effective_date]", date, + "version[status]", status + }; + } + }), + UPDATE_VERSION(new ProjectScopeRedmineRequestBuilder("update_version.xml") { + private static final long serialVersionUID = 1L; + + @Override + public String[] getParameters(Object... args) { + Version version = (Version) args[1]; + String date = getVersionEffectiveDate(version); + String status = getVersionStatus(version); + return new String[]{ + "version[name]", version.getName(), + "version[description]", version.getDescription(), + "version[effective_date]", date, + "version[status]", status + }; + } + }), + NEXT_VERSION(new ProjectScopeRedmineRequestBuilder("next_version.xml") { + private static final long serialVersionUID = 1L; + + @Override + public String[] getParameters(Object... args) { + + + Version version = (Version) args[1]; + String date = getVersionEffectiveDate(version); + String status = getVersionStatus(version); + String oldVersionName = (String) args[2]; + return new String[]{ + "oldVersionName", oldVersionName, + "version[name]", version.getName(), + "version[description]", version.getDescription(), + "version[effective_date]", date, + "version[status]", status + }; + } + }), + ADD_NEWS(new ProjectScopeRedmineRequestBuilder("add_news.xml") { + private static final long serialVersionUID = 1L; + + @Override + public String[] getParameters(Object... args) { + News news = (News) args[1]; + return new String[]{ + "news[title]", news.getTitle(), + "news[summary]", news.getSummary(), + "news[description]", news.getDescription() + }; + } + }), + + // version scope + GET_VERSION(new VersionScopeRedmineRequestBuilder("get_version.xml")), + GET_ISSUE_LIST(new VersionScopeRedmineRequestBuilder("get_version_issues.xml")), + GET_ATTACHMENTS_LIST(new VersionScopeRedmineRequestBuilder("get_version_attachments.xml")), + ADD_ATTACHMENT(new VersionScopeRedmineRequestBuilder("add_version_attachment.xml") { + private static final long serialVersionUID = 1L; + + @Override + public String[] getParameters(Object... args) { + String versionId = (String) args[1]; + Attachment attachment = (Attachment) args[2]; + return new String[]{ + "version_name", versionId, + "attachment[description]", attachment.getDescription() + }; + } + + @Override + public Map<String, File> getAttachments(Object... args) { + Map<String, File> upload = new HashMap<String, File>(); + Attachment attachment = (Attachment) args[2]; + upload.put("attachment[file]", attachment.getToUpload()); + return upload; + } + }), + + // issue scope + + GET_ISSUE_TIME_ENTRY_LIST(new IssueScopeRedmineRequestBuilder("get_issue_times.xml")), + + ADD_ISSUE_TIME_ENTRY(new IssueScopeRedmineRequestBuilder("add_issue_time.xml") { + private static final long serialVersionUID = 1L; + + @Override + public String[] getParameters(Object... args) { + String issueId = (String) args[1]; + TimeEntry timeEntry = (TimeEntry) args[2]; + Date d = timeEntry.getSpentOn(); + if (d == null) { + d = new Date(); + } + String date = DATE_FORMAT.format(d); + return new String[]{ + "issue_id", issueId, + //"timeEntry[issue_id]", issueId, + "time_entry[activity_id]", timeEntry.getActivityId() + "", + "time_entry[spent_on]", date, + "time_entry[hours]", timeEntry.getHours() + "", + "time_entry[comments]", timeEntry.getComments() == null ? "" : timeEntry.getComments() + }; + } + }); + + private final RedmineRequestBuilder requestBuilder; + + DEFAULT_REQUESTS(RedmineRequestBuilder requestBuilder) { + this.requestBuilder = requestBuilder; + } + + public RedmineRequestBuilder getRequestBuilder() { + return requestBuilder; + } + + public String requestName() { + return requestBuilder.getName(); + } + } + + protected static String getVersionStatus(Version version) { + String status = version.getStatus(); + if (Strings.isNullOrEmpty(status)) { + + // use default open status + status = VersionStatusEnum.open.name(); + } + return status; + } + + protected static String getVersionEffectiveDate(Version version) { + return version.getEffectiveDate() == null ? "" : + DATE_FORMAT.format(version.getEffectiveDate()); + } + + +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/RedmineRequestFactory.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/VersionScopeRedmineRequestBuilder.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/VersionScopeRedmineRequestBuilder.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/VersionScopeRedmineRequestBuilder.java 2012-03-25 15:37:26 UTC (rev 256) @@ -0,0 +1,57 @@ +/* + * #%L + * JRedmine :: Client + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.jredmine.request; + +/** + * To build request with a project and version scope. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4 + */ +public class VersionScopeRedmineRequestBuilder extends ProjectScopeRedmineRequestBuilder { + + private static final long serialVersionUID = 1L; + + public VersionScopeRedmineRequestBuilder(String name, String action) { + super(name, action); + } + + public VersionScopeRedmineRequestBuilder(String action) { + super(action); + } + + @Override + public String[] getParameters(Object... args) { + + // args 1 = project id + // args 2 = version name + + String versionName = (String) args[1]; + + return new String[]{ + "version_name", versionName + }; + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/request/VersionScopeRedmineRequestBuilder.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native
participants (1)
-
tchemit@users.nuiton.org