Skip to content

Commit b0485f4

Browse files
committed
Added WDCache to cache folder size and paths for Android App
1 parent 30780be commit b0485f4

File tree

14 files changed

+364
-7
lines changed

14 files changed

+364
-7
lines changed

logicaldoc-webdav/pom.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,16 @@
124124
<dependency>
125125
<groupId>org.springframework</groupId>
126126
<artifactId>spring-tx</artifactId>
127-
<scope>test</scope>
128127
</dependency>
129128
<dependency>
130129
<groupId>org.springframework</groupId>
131130
<artifactId>spring-orm</artifactId>
132131
<scope>test</scope>
133132
</dependency>
133+
<dependency>
134+
<groupId>org.springframework</groupId>
135+
<artifactId>spring-jdbc</artifactId>
136+
</dependency>
134137
<dependency>
135138
<groupId>commons-beanutils</groupId>
136139
<artifactId>commons-beanutils</artifactId>

logicaldoc-webdav/src/main/java/com/logicaldoc/webdav/WebDAVPlugin.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public void install() throws PluginException {
3838
ContextProperties pbean = new ContextProperties();
3939
pbean.setProperty("webdav.enabled", "true");
4040
pbean.setProperty("webdav.depth", "1");
41+
pbean.setProperty("webdav.foldersize.enabled", "true");
4142
pbean.write();
4243
} catch (IOException e) {
4344
log.error(e.getMessage(), e);
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.logicaldoc.webdav.cache;
2+
3+
import java.sql.SQLException;
4+
5+
import javax.sql.DataSource;
6+
7+
import org.apache.commons.lang3.StringUtils;
8+
import org.springframework.dao.DataAccessException;
9+
import org.springframework.jdbc.core.JdbcTemplate;
10+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
11+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
12+
13+
import com.logicaldoc.core.folder.Folder;
14+
15+
public class WDCache {
16+
17+
private DataSource dataSource;
18+
private JdbcTemplate jdbcTemplate;
19+
private static WDCache myself;
20+
21+
public WDCache() throws SQLException {
22+
dataSource = createDataSource();
23+
jdbcTemplate = getTemplate(dataSource);
24+
}
25+
26+
public static WDCache getInstance() {
27+
if (myself == null)
28+
try {
29+
myself = new WDCache();
30+
} catch (SQLException e) {
31+
e.printStackTrace();
32+
}
33+
return myself;
34+
}
35+
36+
private DataSource createDataSource() {
37+
return new EmbeddedDatabaseBuilder()
38+
.setType(EmbeddedDatabaseType.HSQL)
39+
.addScript("classpath:WDCache.sql").build();
40+
}
41+
42+
private JdbcTemplate getTemplate(DataSource dataSource) {
43+
return new JdbcTemplate(dataSource);
44+
}
45+
46+
public int addFolder(WDCacheFolder cf) {
47+
int result = jdbcTemplate.update("UPDATE mycache SET path = ?, size = ? WHERE ID = ?", cf.path, cf.size, cf.id);
48+
if (result == 0)
49+
result = jdbcTemplate.update("INSERT INTO mycache VALUES (?, ?, ?)", cf.id, cf.path, cf.size);
50+
return result;
51+
}
52+
53+
public WDCacheFolder getFolder(long id) {
54+
String query = "SELECT * FROM mycache WHERE ID = ?";
55+
return jdbcTemplate.queryForObject(query, new WDCacheFolderMapper(), id);
56+
}
57+
58+
public long getFolderSize(long id) {
59+
try {
60+
Long result = jdbcTemplate.queryForObject("SELECT size FROM mycache WHERE ID = " +id, Long.class);
61+
if (result != null)
62+
return result.longValue();
63+
} catch (DataAccessException e) {
64+
return 0;
65+
}
66+
return 0;
67+
}
68+
69+
public long getTreeSize(long id) {
70+
try {
71+
Long result = jdbcTemplate.queryForObject("SELECT SUM(size) FROM mycache WHERE path LIKE '%" + id+"%'", Long.class);
72+
if (result != null)
73+
return result.longValue();
74+
} catch (DataAccessException e) {
75+
return 0;
76+
}
77+
return 0;
78+
}
79+
80+
public int countElements() {
81+
try {
82+
return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM mycache", Integer.class);
83+
} catch (DataAccessException e) {
84+
return 0;
85+
}
86+
}
87+
88+
public int setFolderPath(Folder folder) {
89+
if ((folder != null) && !StringUtils.isEmpty(folder.getPath())) {
90+
int result = jdbcTemplate.update("UPDATE mycache SET path = ? WHERE ID = ?", folder.getPath(), folder.getId());
91+
if (result == 0) {
92+
result = jdbcTemplate.update("INSERT INTO mycache VALUES (?, ?, ?)", folder.getId(), folder.getPath(), 0);
93+
}
94+
return result;
95+
}
96+
return 0;
97+
}
98+
99+
public String getFolderPath(long folderID) {
100+
try {
101+
return jdbcTemplate.queryForObject("SELECT path FROM mycache WHERE ID = " + folderID, String.class);
102+
} catch (DataAccessException e) {
103+
return null;
104+
}
105+
}
106+
107+
public int truncate() {
108+
return jdbcTemplate.update("DELETE FROM mycache");
109+
}
110+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.logicaldoc.webdav.cache;
2+
3+
public class WDCacheFolder {
4+
5+
public long id;
6+
public String path;
7+
public long size;
8+
9+
public WDCacheFolder(long folderID, String path, long folderSize) {
10+
this.id = folderID;
11+
this.path = path;
12+
this.size = folderSize;
13+
}
14+
15+
public WDCacheFolder() {
16+
}
17+
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.logicaldoc.webdav.cache;
2+
3+
import java.sql.ResultSet;
4+
import java.sql.SQLException;
5+
6+
import org.springframework.jdbc.core.RowMapper;
7+
8+
public class WDCacheFolderMapper implements RowMapper<WDCacheFolder> {
9+
@Override
10+
public WDCacheFolder mapRow(ResultSet rs, int rowNum) throws SQLException {
11+
WDCacheFolder wcf = new WDCacheFolder();
12+
13+
wcf.id = rs.getLong("ID");
14+
wcf.path = rs.getString("path");
15+
wcf.size = rs.getLong("size");
16+
17+
return wcf;
18+
}
19+
}

logicaldoc-webdav/src/main/java/com/logicaldoc/webdav/resource/DavResourceImpl.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,18 @@ private void addPermissionsProperty(DavPropertyName name, Namespace nameSpace) {
310310
}
311311

312312
private void addSizeProperty(DavPropertyName name, Namespace nameSpace) {
313-
if (name.getName().equals("size") && !isCollection() && !resource.isFolder()) {
314-
DefaultDavProperty<Long> defaultDavProperty = new DefaultDavProperty<>("size", resource.getContentLength(),
315-
nameSpace);
316-
properties.add(defaultDavProperty);
317-
}
313+
if (name.getName().equals("size")) {
314+
if (!isCollection() && !resource.isFolder()) {
315+
DefaultDavProperty<Long> defaultDavProperty = new DefaultDavProperty<>("size", resource.getContentLength(),
316+
nameSpace);
317+
properties.add(defaultDavProperty);
318+
}
319+
if (isCollection() && resource.isFolder()) {
320+
DefaultDavProperty<Long> defaultDavProperty = new DefaultDavProperty<>("size", resource.getSize(),
321+
nameSpace);
322+
properties.add(defaultDavProperty);
323+
}
324+
}
318325
}
319326

320327
private void addIdProperty(Namespace nameSpace) {

logicaldoc-webdav/src/main/java/com/logicaldoc/webdav/resource/model/Resource.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* logicalDOC. Secure handlings will be managed through this.
1717
*
1818
* @author Sebastian Wenzky
19+
* @author Alessandro Gasparini
1920
*/
2021
public interface Resource {
2122

@@ -120,4 +121,8 @@ public interface Resource {
120121
public void setETag(String string);
121122

122123
public String getETag();
124+
125+
public void setSize(long l);
126+
127+
public long getSize();
123128
}

logicaldoc-webdav/src/main/java/com/logicaldoc/webdav/resource/model/ResourceImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ public class ResourceImpl implements Resource {
7777
WebdavSession session;
7878

7979
private String eTag;
80+
81+
private long size;
8082

8183
public Long getContentLength() {
8284
return contentLength;
@@ -374,4 +376,14 @@ public void setETag(String eTag) {
374376
public String getETag() {
375377
return this.eTag;
376378
}
379+
380+
381+
@Override
382+
public void setSize(long size) {
383+
this.size = size;
384+
}
385+
@Override
386+
public long getSize() {
387+
return size;
388+
}
377389
}

logicaldoc-webdav/src/main/java/com/logicaldoc/webdav/resource/service/ResourceServiceImpl.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,13 @@
4141
import com.logicaldoc.core.security.user.UserDAO;
4242
import com.logicaldoc.core.store.Store;
4343
import com.logicaldoc.util.Context;
44+
import com.logicaldoc.webdav.cache.WDCache;
45+
import com.logicaldoc.webdav.cache.WDCacheFolder;
4446
import com.logicaldoc.webdav.context.ImportContext;
4547
import com.logicaldoc.webdav.resource.model.Resource;
4648
import com.logicaldoc.webdav.resource.model.ResourceImpl;
4749
import com.logicaldoc.webdav.session.WebdavSession;
50+
import com.logicaldoc.webdav.web.WebdavServlet;
4851

4952
/**
5053
* Base implementation of a {@link ResourceService}
@@ -75,6 +78,8 @@ public class ResourceServiceImpl implements ResourceService {
7578

7679
@javax.annotation.Resource(name = "UserDAO")
7780
private transient UserDAO userDAO;
81+
82+
private static WDCache wdc = WDCache.getInstance();
7883

7984
public void setUserDAO(UserDAO userDAO) {
8085
this.userDAO = userDAO;
@@ -104,6 +109,7 @@ private Resource marshallFolder(Folder folder, WebdavSession session) {
104109
Resource resource = new ResourceImpl();
105110
resource.setID(String.valueOf(folder.getId()));
106111
resource.setContentLength(0L);
112+
resource.setSize(0L);
107113
resource.setName(folder.getName());
108114
resource.setLastModified(folder.getLastModified());
109115

@@ -117,6 +123,20 @@ private Resource marshallFolder(Folder folder, WebdavSession session) {
117123
if (session != null && (Long) session.getObject("id") != null) {
118124
resource.setRequestedPerson((Long) session.getObject("id"));
119125
}
126+
127+
if (WebdavServlet.foldersizeEnabled) {
128+
// update folder path
129+
wdc.setFolderPath(folder);
130+
131+
long fsize = wdc.getFolderSize(folder.getId());
132+
log.debug("folderSize: {}", fsize);
133+
fsize = wdc.getTreeSize(folder.getId());
134+
log.debug("treeSize: {}", fsize);
135+
if (fsize > 0) {
136+
resource.setSize(fsize);
137+
}
138+
}
139+
120140

121141
return resource;
122142
}
@@ -184,6 +204,8 @@ public List<Resource> getChildResources(Resource parentResource) throws DavExcep
184204

185205
private void getDocumentChildren(Resource parentResource, List<Resource> resourceList, User user)
186206
throws PersistenceException {
207+
208+
long folderSize = 0;
187209

188210
Collection<Document> documents = documentDAO.findByFileNameAndParentFolderId(
189211
Long.parseLong(parentResource.getID()), "", null, user.getTenantId(), null);
@@ -193,8 +215,28 @@ private void getDocumentChildren(Resource parentResource, List<Resource> resourc
193215
} catch (Exception t) {
194216
continue;
195217
}
218+
folderSize += document.getFileSize();
196219
resourceList.add(marshallDocument(document, parentResource.getSession()));
197220
}
221+
222+
if (WebdavServlet.foldersizeEnabled) {
223+
log.debug("getID: {}, folderName: {}, Size: {}", parentResource.getID(), parentResource.getName(), folderSize);
224+
225+
long folderID = Long.parseLong(parentResource.getID());
226+
227+
// check if path is already calculated
228+
String fpath = wdc.getFolderPath(folderID);
229+
if (StringUtils.isEmpty(fpath)) {
230+
// calculate the path of the folder only if needed
231+
fpath = folderDAO.computePath(folderID);
232+
log.debug("computed Path: {}", fpath);
233+
}
234+
235+
// Add the WDCacheFolder to the cache
236+
WDCacheFolder cf = new WDCacheFolder(folderID, fpath, folderSize);
237+
int result = wdc.addFolder(cf);
238+
log.debug("result: {}", result);
239+
}
198240
}
199241

200242
private boolean isFolderAccessible(Resource parentResource, final Long folderID) throws PersistenceException {

logicaldoc-webdav/src/main/java/com/logicaldoc/webdav/web/AbstractWebdavServlet.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,20 @@ public void service(HttpServletRequest request, HttpServletResponse response) {
123123
log.debug("method {} {}", request.getMethod(), methodCode);
124124

125125
Session session = SessionManager.get().getSession(request);
126-
if (session == null)
126+
if (session == null) {
127+
// Try to invalidates previous session cookie
128+
if (request.getCookies().length > 0) {
129+
Cookie[] cooks = request.getCookies();
130+
for (Cookie cookie : cooks) {
131+
if (cookie.getName().equals("ldoc-sid")) {
132+
// A zero value causes the cookie to be deleted.
133+
cookie.setMaxAge(0);
134+
webdavResponse.addCookie(cookie);
135+
}
136+
}
137+
}
127138
throw new DavException(HttpServletResponse.SC_UNAUTHORIZED);
139+
}
128140

129141
SessionManager.get().renew(session.getSid());
130142

@@ -141,6 +153,7 @@ public void service(HttpServletRequest request, HttpServletResponse response) {
141153

142154
// Add session cookie to the response
143155
Cookie scookie = new Cookie("ldoc-sid", session.getSid());
156+
scookie.setMaxAge(1800);
144157
webdavResponse.addCookie(scookie);
145158

146159
getPath(webdavRequest);

0 commit comments

Comments
 (0)