Skip to content

Commit 840a4dd

Browse files
author
Denis Anisimov
committedDec 10, 2016
Some implementation solutions in order to keep API good.
1 parent 3ffe561 commit 840a4dd

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package api;
2+
3+
import api.VirtualFileSystem.AbstractVirtualFile;
4+
import api.VirtualFileSystem.ApiClassFactory;
5+
import spi.ServiceProvider;
6+
7+
/**
8+
* @author denis
9+
*
10+
*/
11+
public final class VirtualFile extends AbstractVirtualFile {
12+
13+
private VirtualFile(ServiceProvider provider, String id) {
14+
super(provider, id);
15+
}
16+
17+
public final byte[] getBinaryContent() {
18+
return getProvider().getData(getId());
19+
}
20+
21+
private static class ApiClassFactoryImpl extends ApiClassFactory {
22+
23+
static {
24+
INSTANCE = new ApiClassFactoryImpl();
25+
}
26+
27+
@Override
28+
protected VirtualFile create(ServiceProvider provider, String id) {
29+
return new VirtualFile(provider, id);
30+
}
31+
32+
}
33+
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package api;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Iterator;
6+
import java.util.List;
7+
import java.util.Optional;
8+
import java.util.ServiceLoader;
9+
import java.util.stream.Collectors;
10+
11+
import spi.ServiceProvider;
12+
13+
/**
14+
* @author denis
15+
*
16+
*/
17+
public final class VirtualFileSystem {
18+
19+
private VirtualFileSystem() {
20+
}
21+
22+
private static final VirtualFileSystem INSTANCE = new VirtualFileSystem();
23+
24+
public static VirtualFileSystem getInstance() {
25+
return INSTANCE;
26+
}
27+
28+
public VirtualFile getFile(String id) {
29+
Optional<ServiceProvider> provider = ApiClassFactory.PROVIDERS.stream().filter(service -> service.ownsId(id))
30+
.findFirst();
31+
if (provider.isPresent()) {
32+
return ApiClassFactory.INSTANCE.create(provider.get(), id);
33+
}
34+
return null;
35+
}
36+
37+
public List<String> getFileIds() {
38+
return ApiClassFactory.PROVIDERS.stream().flatMap(provider -> provider.getIds().stream())
39+
.collect(Collectors.toList());
40+
}
41+
42+
public String getPath(VirtualFile file) {
43+
AbstractVirtualFile virtualFile = file;
44+
return virtualFile.getProvider().getPath(virtualFile.getId());
45+
}
46+
47+
static class AbstractVirtualFile {
48+
49+
protected AbstractVirtualFile(ServiceProvider provider, String id) {
50+
myProvider = provider;
51+
myId = id;
52+
}
53+
54+
protected ServiceProvider getProvider() {
55+
return myProvider;
56+
}
57+
58+
protected String getId() {
59+
return myId;
60+
}
61+
62+
private final String myId;
63+
64+
private final ServiceProvider myProvider;
65+
}
66+
67+
public static abstract class ApiClassFactory {
68+
69+
protected static ApiClassFactory INSTANCE;
70+
71+
private static final Collection<ServiceProvider> PROVIDERS = loadProviders();
72+
73+
static {
74+
loadImpl();
75+
}
76+
77+
protected abstract VirtualFile create(ServiceProvider provider, String id);
78+
79+
private static void loadImpl() {
80+
try {
81+
Class.forName(VirtualFile.class.getName() + "$ApiClassFactoryImpl");
82+
} catch (ClassNotFoundException e) {
83+
throw new RuntimeException(e);
84+
}
85+
}
86+
87+
private static Collection<ServiceProvider> loadProviders() {
88+
Iterator<ServiceProvider> iterator = ServiceLoader.load(ServiceProvider.class).iterator();
89+
Collection<ServiceProvider> providers = new ArrayList<>();
90+
for (; iterator.hasNext();) {
91+
providers.add(iterator.next());
92+
}
93+
return providers;
94+
}
95+
}
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package spi;
2+
3+
import java.util.Collection;
4+
5+
/**
6+
* @author denis
7+
*
8+
*/
9+
public interface ServiceProvider {
10+
11+
byte[] getData(String id);
12+
13+
Collection<String> getIds();
14+
15+
boolean ownsId(String id);
16+
17+
String getPath(String id);
18+
}

0 commit comments

Comments
 (0)
Please sign in to comment.