1 /***
2 * Simple Web Spider - <http://simplewebspider.sourceforge.net/>
3 * Copyright (C) 2009 <berendona@users.sourceforge.net>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package simplespider.simplespider.dao.db4o;
20
21 import java.io.IOException;
22 import java.sql.SQLException;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import simplespider.simplespider.dao.DbHelper;
28 import simplespider.simplespider.dao.DbHelperFactory;
29
30 import com.db4o.ObjectContainer;
31 import com.db4o.ObjectServer;
32 import com.db4o.constraints.UniqueFieldValueConstraint;
33 import com.db4o.cs.Db4oClientServer;
34 import com.db4o.cs.config.ServerConfiguration;
35 import com.db4o.defragment.Defragment;
36 import com.db4o.diagnostic.ClassHasNoFields;
37 import com.db4o.diagnostic.Diagnostic;
38 import com.db4o.diagnostic.DiagnosticBase;
39 import com.db4o.diagnostic.DiagnosticListener;
40 import com.db4o.ext.ExtObjectContainer;
41 import com.db4o.ext.SystemInfo;
42 import com.db4o.reflect.ReflectClass;
43
44 public class Db4oDbHelperFactory implements DbHelperFactory {
45
46 private static final Log LOG = LogFactory.getLog(Db4oDbHelperFactory.class);
47
48 private ObjectServer server;
49
50 public Db4oDbHelperFactory(final String filename) {
51
52 final ServerConfiguration dbConfig = Db4oClientServer.newServerConfiguration();
53 dbConfig.common().objectClass(Hash.class).objectField(Hash.HASH).indexed(true);
54 dbConfig.common().add(new UniqueFieldValueConstraint(Hash.class, Hash.HASH));
55
56 dbConfig.common().allowVersionUpdates(true);
57 dbConfig.common().detectSchemaChanges(true);
58 dbConfig.common().exceptionsOnNotStorable(true);
59 dbConfig.common().optimizeNativeQueries(true);
60 dbConfig.common().messageLevel(1);
61 dbConfig.common().activationDepth(1);
62
63 if (LOG.isDebugEnabled()) {
64 dbConfig.common().diagnostic().addListener(new DiagnosticListener() {
65 public void onDiagnostic(final Diagnostic arg0) {
66
67 if (arg0 instanceof ClassHasNoFields) {
68 return;
69 }
70 if (arg0 instanceof DiagnosticBase) {
71 final DiagnosticBase d = (DiagnosticBase) arg0;
72 LOG.debug("Diagnostic: " + d.getClass() + " : " + d.problem() + " : " + d.solution() + " : " + d.reason(), new Exception(
73 "debug"));
74 } else {
75 LOG.debug("Diagnostic: " + arg0 + " : " + arg0.getClass(), new Exception("debug"));
76 }
77 }
78 });
79 }
80
81
82
83
84 dbConfig.common().automaticShutDown(false);
85
86
87
88
89
90
91
92
93 dbConfig.file().freespace().useBTreeSystem();
94
95
96
97
98 dbConfig.file().blockSize(8);
99
100 if (LOG.isInfoEnabled()) {
101 LOG.info("Start defragmentation database file... This could took some while...");
102 }
103 try {
104 Defragment.defrag(filename);
105 } catch (final IOException e) {
106 LOG.warn("Failed to defragment database file \"" + filename + "\"", e);
107 }
108
109 if (LOG.isInfoEnabled()) {
110 LOG.info("Opening database file... This could took some while...");
111 }
112 try {
113 this.server = Db4oClientServer.openServer(dbConfig, filename, 0);
114 } catch (final RuntimeException e) {
115 throw new RuntimeException("Failed to open database file \"" + filename + "\"", e);
116 }
117
118 if (LOG.isInfoEnabled()) {
119 final ObjectContainer container = getConnection();
120 try {
121 final ExtObjectContainer ext = container.ext();
122
123 final ReflectClass[] knownClasses = ext.knownClasses();
124 final StringBuffer sb = new StringBuffer();
125 sb.append("Known classes: ");
126 for (final ReflectClass knownClass : knownClasses) {
127 sb.append(knownClass.getName());
128 sb.append(";");
129 }
130 LOG.info(sb.toString());
131
132 final SystemInfo systemInfo = ext.systemInfo();
133 LOG.info("Total size: " + systemInfo.totalSize());
134 LOG.info("Freespace size: " + systemInfo.freespaceSize());
135 LOG.info("Freespace entry count: " + systemInfo.freespaceEntryCount());
136
137 } finally {
138 container.close();
139 }
140 }
141 }
142
143 @Override
144 public DbHelper buildDbHelper() throws SQLException {
145 final Db4oDbHelper dbHelper = new Db4oDbHelper();
146
147 dbHelper.createConnection(this);
148 return dbHelper;
149 }
150
151 ObjectContainer getConnection() {
152 return this.server.openClient();
153 }
154
155 void shutdown() {
156 this.server.close();
157 this.server = null;
158 }
159
160 }