mirror of
https://github.com/sismics/docs.git
synced 2024-11-25 23:27:57 +01:00
commit
f80cf43ae8
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.sismics.docs</groupId>
|
<groupId>com.sismics.docs</groupId>
|
||||||
<artifactId>docs-parent</artifactId>
|
<artifactId>docs-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.4-SNAPSHOT</version>
|
||||||
<relativePath>..</relativePath>
|
<relativePath>..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
package com.sismics.docs.core.dao.jpa;
|
package com.sismics.docs.core.dao.jpa;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
@ -8,11 +14,8 @@ import javax.persistence.Query;
|
|||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.sismics.docs.core.constant.AuditLogType;
|
import com.sismics.docs.core.constant.AuditLogType;
|
||||||
import com.sismics.docs.core.dao.jpa.criteria.GroupCriteria;
|
|
||||||
import com.sismics.docs.core.dao.jpa.criteria.TagCriteria;
|
import com.sismics.docs.core.dao.jpa.criteria.TagCriteria;
|
||||||
import com.sismics.docs.core.dao.jpa.dto.GroupDto;
|
|
||||||
import com.sismics.docs.core.dao.jpa.dto.TagDto;
|
import com.sismics.docs.core.dao.jpa.dto.TagDto;
|
||||||
import com.sismics.docs.core.dao.jpa.dto.TagStatDto;
|
|
||||||
import com.sismics.docs.core.model.jpa.DocumentTag;
|
import com.sismics.docs.core.model.jpa.DocumentTag;
|
||||||
import com.sismics.docs.core.model.jpa.Tag;
|
import com.sismics.docs.core.model.jpa.Tag;
|
||||||
import com.sismics.docs.core.util.AuditLogUtil;
|
import com.sismics.docs.core.util.AuditLogUtil;
|
||||||
|
@ -5,7 +5,6 @@ import java.io.FilenameFilter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Writer;
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
@ -9,7 +9,6 @@ import org.junit.Assert;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.io.ByteStreams;
|
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
import com.sismics.docs.core.dao.jpa.dto.DocumentDto;
|
import com.sismics.docs.core.dao.jpa.dto.DocumentDto;
|
||||||
import com.sismics.docs.core.model.jpa.File;
|
import com.sismics.docs.core.model.jpa.File;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.sismics.docs</groupId>
|
<groupId>com.sismics.docs</groupId>
|
||||||
<artifactId>docs-parent</artifactId>
|
<artifactId>docs-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.4-SNAPSHOT</version>
|
||||||
<relativePath>..</relativePath>
|
<relativePath>..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.sismics.docs</groupId>
|
<groupId>com.sismics.docs</groupId>
|
||||||
<artifactId>docs-parent</artifactId>
|
<artifactId>docs-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.4-SNAPSHOT</version>
|
||||||
<relativePath>..</relativePath>
|
<relativePath>..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ public class ClientUtil {
|
|||||||
* Creates a group.
|
* Creates a group.
|
||||||
*
|
*
|
||||||
* @param name Name
|
* @param name Name
|
||||||
* @param parent Parent
|
* @param parentId Parent ID
|
||||||
*/
|
*/
|
||||||
public void createGroup(String name, String parentId) {
|
public void createGroup(String name, String parentId) {
|
||||||
// Login admin to create the group
|
// Login admin to create the group
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.sismics.docs</groupId>
|
<groupId>com.sismics.docs</groupId>
|
||||||
<artifactId>docs-parent</artifactId>
|
<artifactId>docs-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.4-SNAPSHOT</version>
|
||||||
<relativePath>..</relativePath>
|
<relativePath>..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -209,7 +209,8 @@ public class AppResource extends BaseResource {
|
|||||||
sb.append(" left join T_FILE f on f.FIL_ID_C = al.LOG_IDENTITY_C and f.FIL_DELETEDATE_D is null ");
|
sb.append(" left join T_FILE f on f.FIL_ID_C = al.LOG_IDENTITY_C and f.FIL_DELETEDATE_D is null ");
|
||||||
sb.append(" left join T_TAG t on t.TAG_ID_C = al.LOG_IDENTITY_C and t.TAG_DELETEDATE_D is null ");
|
sb.append(" left join T_TAG t on t.TAG_ID_C = al.LOG_IDENTITY_C and t.TAG_DELETEDATE_D is null ");
|
||||||
sb.append(" left join T_USER u on u.USE_ID_C = al.LOG_IDENTITY_C and u.USE_DELETEDATE_D is null ");
|
sb.append(" left join T_USER u on u.USE_ID_C = al.LOG_IDENTITY_C and u.USE_DELETEDATE_D is null ");
|
||||||
sb.append(" where d.DOC_ID_C is null and a.ACL_ID_C is null and c.COM_ID_C is null and f.FIL_ID_C is null and t.TAG_ID_C is null and u.USE_ID_C is null)");
|
sb.append(" left join T_GROUP g on g.GRP_ID_C = al.LOG_IDENTITY_C and g.GRP_DELETEDATE_D is null ");
|
||||||
|
sb.append(" where d.DOC_ID_C is null and a.ACL_ID_C is null and c.COM_ID_C is null and f.FIL_ID_C is null and t.TAG_ID_C is null and u.USE_ID_C is null and g.GRP_ID_C is null)");
|
||||||
Query q = em.createNativeQuery(sb.toString());
|
Query q = em.createNativeQuery(sb.toString());
|
||||||
log.info("Deleting {} orphan audit logs", q.executeUpdate());
|
log.info("Deleting {} orphan audit logs", q.executeUpdate());
|
||||||
|
|
||||||
@ -217,8 +218,10 @@ public class AppResource extends BaseResource {
|
|||||||
sb = new StringBuilder("update T_ACL a set ACL_DELETEDATE_D = :dateNow where a.ACL_ID_C in (select a.ACL_ID_C from T_ACL a ");
|
sb = new StringBuilder("update T_ACL a set ACL_DELETEDATE_D = :dateNow where a.ACL_ID_C in (select a.ACL_ID_C from T_ACL a ");
|
||||||
sb.append(" left join T_SHARE s on s.SHA_ID_C = a.ACL_TARGETID_C ");
|
sb.append(" left join T_SHARE s on s.SHA_ID_C = a.ACL_TARGETID_C ");
|
||||||
sb.append(" left join T_USER u on u.USE_ID_C = a.ACL_TARGETID_C ");
|
sb.append(" left join T_USER u on u.USE_ID_C = a.ACL_TARGETID_C ");
|
||||||
|
sb.append(" left join T_GROUP g on g.GRP_ID_C = a.ACL_TARGETID_C ");
|
||||||
sb.append(" left join T_DOCUMENT d on d.DOC_ID_C = a.ACL_SOURCEID_C ");
|
sb.append(" left join T_DOCUMENT d on d.DOC_ID_C = a.ACL_SOURCEID_C ");
|
||||||
sb.append(" where s.SHA_ID_C is null and u.USE_ID_C is null or d.DOC_ID_C is null)");
|
sb.append(" left join T_TAG t on t.TAG_ID_C = a.ACL_SOURCEID_C ");
|
||||||
|
sb.append(" where s.SHA_ID_C is null and u.USE_ID_C is null and g.GRP_ID_C is null or d.DOC_ID_C is null and t.TAG_ID_C is null)");
|
||||||
q = em.createNativeQuery(sb.toString());
|
q = em.createNativeQuery(sb.toString());
|
||||||
q.setParameter("dateNow", new Date());
|
q.setParameter("dateNow", new Date());
|
||||||
log.info("Deleting {} orphan ACLs", q.executeUpdate());
|
log.info("Deleting {} orphan ACLs", q.executeUpdate());
|
||||||
@ -262,6 +265,7 @@ public class AppResource extends BaseResource {
|
|||||||
log.info("Deleting {} soft deleted files", em.createQuery("delete File f where f.deleteDate is not null").executeUpdate());
|
log.info("Deleting {} soft deleted files", em.createQuery("delete File f where f.deleteDate is not null").executeUpdate());
|
||||||
log.info("Deleting {} soft deleted documents", em.createQuery("delete Document d where d.deleteDate is not null").executeUpdate());
|
log.info("Deleting {} soft deleted documents", em.createQuery("delete Document d where d.deleteDate is not null").executeUpdate());
|
||||||
log.info("Deleting {} soft deleted users", em.createQuery("delete User u where u.deleteDate is not null").executeUpdate());
|
log.info("Deleting {} soft deleted users", em.createQuery("delete User u where u.deleteDate is not null").executeUpdate());
|
||||||
|
log.info("Deleting {} soft deleted groups", em.createQuery("delete Group g where g.deleteDate is not null").executeUpdate());
|
||||||
|
|
||||||
// Always return OK
|
// Always return OK
|
||||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||||
@ -344,10 +348,8 @@ public class AppResource extends BaseResource {
|
|||||||
AclDao aclDao = new AclDao();
|
AclDao aclDao = new AclDao();
|
||||||
List<AclDto> aclDtoList = aclDao.getBySourceId(tagDto.getId());
|
List<AclDto> aclDtoList = aclDao.getBySourceId(tagDto.getId());
|
||||||
String userId = userDao.getActiveByUsername(tagDto.getCreator()).getId();
|
String userId = userDao.getActiveByUsername(tagDto.getCreator()).getId();
|
||||||
for (AclDto aclDto : aclDtoList) {
|
|
||||||
aclDao.delete(aclDto.getSourceId(), aclDto.getPerm(), aclDto.getTargetId(), userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (aclDtoList.size() == 0) {
|
||||||
// Create read ACL
|
// Create read ACL
|
||||||
Acl acl = new Acl();
|
Acl acl = new Acl();
|
||||||
acl.setPerm(PermType.READ);
|
acl.setPerm(PermType.READ);
|
||||||
@ -362,6 +364,7 @@ public class AppResource extends BaseResource {
|
|||||||
acl.setTargetId(userId);
|
acl.setTargetId(userId);
|
||||||
aclDao.create(acl, userId);
|
aclDao.create(acl, userId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Always return OK
|
// Always return OK
|
||||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||||
|
@ -37,10 +37,6 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
@Path("/theme")
|
@Path("/theme")
|
||||||
public class ThemeResource extends BaseResource {
|
public class ThemeResource extends BaseResource {
|
||||||
// Filenames for images in theme directory
|
|
||||||
private static final String LOGO_IMAGE = "logo";
|
|
||||||
private static final String BACKGROUND_IMAGE = "background";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns custom CSS stylesheet.
|
* Returns custom CSS stylesheet.
|
||||||
*
|
*
|
||||||
@ -162,7 +158,7 @@ public class ThemeResource extends BaseResource {
|
|||||||
if (Files.exists(filePath)) {
|
if (Files.exists(filePath)) {
|
||||||
inputStream = Files.newInputStream(filePath);
|
inputStream = Files.newInputStream(filePath);
|
||||||
} else {
|
} else {
|
||||||
inputStream = getClass().getResource("/image/" + (type.equals(LOGO_IMAGE) ? "logo.png" : "background.jpg")).openStream();
|
inputStream = getClass().getResource("/image/" + (type.equals("logo") ? "logo.png" : "background.jpg")).openStream();
|
||||||
}
|
}
|
||||||
ByteStreams.copy(inputStream, outputStream);
|
ByteStreams.copy(inputStream, outputStream);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -7,7 +7,7 @@ angular.module('docs').controller('DocumentViewPermissions', function($scope) {
|
|||||||
// Watch for ACLs change and group them for easy displaying
|
// Watch for ACLs change and group them for easy displaying
|
||||||
$scope.$watch('document.inherited_acls', function(acls) {
|
$scope.$watch('document.inherited_acls', function(acls) {
|
||||||
$scope.inheritedAcls = _.groupBy(acls, function(acl) {
|
$scope.inheritedAcls = _.groupBy(acls, function(acl) {
|
||||||
return acl.source_id;
|
return acl.source_id + acl.id;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -3,13 +3,16 @@
|
|||||||
/**
|
/**
|
||||||
* Tag controller.
|
* Tag controller.
|
||||||
*/
|
*/
|
||||||
angular.module('docs').controller('Tag', function($scope, $dialog, Restangular, $state) {
|
angular.module('docs').controller('Tag', function($scope, Restangular, $state) {
|
||||||
$scope.tag = { name: '', color: '#3a87ad' };
|
$scope.tag = { name: '', color: '#3a87ad' };
|
||||||
|
|
||||||
// Retrieve tags
|
// Retrieve tags
|
||||||
|
$scope.loadTags = function() {
|
||||||
Restangular.one('tag/list').get().then(function(data) {
|
Restangular.one('tag/list').get().then(function(data) {
|
||||||
$scope.tags = data.tags;
|
$scope.tags = data.tags;
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
$scope.loadTags();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a tag.
|
* Display a tag.
|
||||||
@ -27,26 +30,4 @@ angular.module('docs').controller('Tag', function($scope, $dialog, Restangular,
|
|||||||
$scope.tag = { name: '', color: '#3a87ad' };
|
$scope.tag = { name: '', color: '#3a87ad' };
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a tag.
|
|
||||||
*/
|
|
||||||
$scope.deleteTag = function(tag) {
|
|
||||||
var title = 'Delete tag';
|
|
||||||
var msg = 'Do you really want to delete this tag?';
|
|
||||||
var btns = [
|
|
||||||
{result: 'cancel', label: 'Cancel'},
|
|
||||||
{result: 'ok', label: 'OK', cssClass: 'btn-primary'}
|
|
||||||
];
|
|
||||||
|
|
||||||
$dialog.messageBox(title, msg, btns, function(result) {
|
|
||||||
if (result == 'ok') {
|
|
||||||
Restangular.one('tag', tag.id).remove().then(function() {
|
|
||||||
$scope.tags = _.reject($scope.tags, function(t) {
|
|
||||||
return tag.id == t.id;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
});
|
});
|
@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* Tag edit controller.
|
* Tag edit controller.
|
||||||
*/
|
*/
|
||||||
angular.module('docs').controller('TagEdit', function($scope, $stateParams, Restangular) {
|
angular.module('docs').controller('TagEdit', function($scope, $stateParams, Restangular, $dialog, $state) {
|
||||||
// Retrieve the tag
|
// Retrieve the tag
|
||||||
Restangular.one('tag', $stateParams.id).get().then(function(data) {
|
Restangular.one('tag', $stateParams.id).get().then(function(data) {
|
||||||
$scope.tag = data;
|
$scope.tag = data;
|
||||||
@ -23,4 +23,25 @@ angular.module('docs').controller('TagEdit', function($scope, $stateParams, Rest
|
|||||||
// Update the server
|
// Update the server
|
||||||
Restangular.one('tag', $scope.tag.id).post('', $scope.tag);
|
Restangular.one('tag', $scope.tag.id).post('', $scope.tag);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a tag.
|
||||||
|
*/
|
||||||
|
$scope.deleteTag = function(tag) {
|
||||||
|
var title = 'Delete tag';
|
||||||
|
var msg = 'Do you really want to delete this tag?';
|
||||||
|
var btns = [
|
||||||
|
{result: 'cancel', label: 'Cancel'},
|
||||||
|
{result: 'ok', label: 'OK', cssClass: 'btn-primary'}
|
||||||
|
];
|
||||||
|
|
||||||
|
$dialog.messageBox(title, msg, btns, function(result) {
|
||||||
|
if (result == 'ok') {
|
||||||
|
Restangular.one('tag', tag.id).remove().then(function() {
|
||||||
|
$scope.loadTags();
|
||||||
|
$state.go('tag.default');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
});
|
});
|
@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-show="document">
|
<div ng-show="document">
|
||||||
<div class="text-right" ng-show="document.writable">
|
<div class="pull-right" ng-show="document.writable">
|
||||||
<div class="btn-group dropdown" dropdown>
|
<div class="btn-group dropdown" dropdown>
|
||||||
<button class="btn btn-default" dropdown-toggle>
|
<button class="btn btn-default" dropdown-toggle>
|
||||||
<span class="glyphicon glyphicon-export"></span>
|
<span class="glyphicon glyphicon-export"></span>
|
||||||
|
@ -41,9 +41,10 @@
|
|||||||
<label class="col-sm-2 control-label">Groups</label>
|
<label class="col-sm-2 control-label">Groups</label>
|
||||||
|
|
||||||
<div class="col-sm-7">
|
<div class="col-sm-7">
|
||||||
|
<span ng-repeat="group in user.groups">
|
||||||
<a class="btn btn-default"
|
<a class="btn btn-default"
|
||||||
ng-repeat="group in user.groups"
|
href="#/settings/group/edit/{{ group }}">{{ group }}</a>
|
||||||
href="#/settings/group/edit/{{ group }}">{{ group }}</a>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" ng-class="{ 'has-error': !editUserForm.storage_quota.$valid, success: editUserForm.storage_quota.$valid }">
|
<div class="form-group" ng-class="{ 'has-error': !editUserForm.storage_quota.$valid, success: editUserForm.storage_quota.$valid }">
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
<h1>{{ tag.name }} </h1>
|
<div class="pull-right" ng-show="tag.writable">
|
||||||
|
<button class="btn btn-danger" ng-click="deleteTag(tag)"><span class="glyphicon glyphicon-trash"></span> Delete</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="well col-lg-8">
|
<div class="page-header">
|
||||||
|
<h1>{{ tag.name }} </h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="well col-lg-8" ng-show="tag.writable">
|
||||||
<form class="form-horizontal" name="editTagForm" novalidate>
|
<form class="form-horizontal" name="editTagForm" novalidate>
|
||||||
<div class="form-group" ng-class="{ 'has-error': !editTagForm.name.$valid, success: editTagForm.name.$valid }">
|
<div class="form-group" ng-class="{ 'has-error': !editTagForm.name.$valid, success: editTagForm.name.$valid }">
|
||||||
<label class="col-sm-2 control-label" for="inputName">Name</label>
|
<label class="col-sm-2 control-label" for="inputName">Name</label>
|
||||||
@ -29,7 +35,7 @@
|
|||||||
<option ng-repeat="tag0 in tags"
|
<option ng-repeat="tag0 in tags"
|
||||||
ng-if="tag0.id != tag.id"
|
ng-if="tag0.id != tag.id"
|
||||||
ng-selected="tag.parent == tag0.id"
|
ng-selected="tag.parent == tag0.id"
|
||||||
value="{{ tag0.id }}">Parent: {{ tag0.name }}</option>
|
value="{{ tag0.id }}">{{ tag0.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,11 +29,6 @@
|
|||||||
<span class="glyphicon glyphicon-pencil"></span>
|
<span class="glyphicon glyphicon-pencil"></span>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-xs-1">
|
|
||||||
<button class="btn btn-danger pull-right" ng-click="deleteTag(tag)" title="Delete this tag">
|
|
||||||
<span class="glyphicon glyphicon-trash"></span>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -2,7 +2,6 @@ package com.sismics.docs.rest;
|
|||||||
|
|
||||||
import javax.json.JsonArray;
|
import javax.json.JsonArray;
|
||||||
import javax.json.JsonObject;
|
import javax.json.JsonObject;
|
||||||
import javax.json.JsonValue;
|
|
||||||
import javax.ws.rs.client.Entity;
|
import javax.ws.rs.client.Entity;
|
||||||
import javax.ws.rs.core.Form;
|
import javax.ws.rs.core.Form;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
|||||||
<groupId>com.sismics.docs</groupId>
|
<groupId>com.sismics.docs</groupId>
|
||||||
<artifactId>docs-parent</artifactId>
|
<artifactId>docs-parent</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.4-SNAPSHOT</version>
|
||||||
|
|
||||||
<name>Docs Parent</name>
|
<name>Docs Parent</name>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user