]> WPIA git - gigi.git/blob - src/org/cacert/gigi/dbObjects/Domain.java
FIX: synchronization for IDCachable-Objects
[gigi.git] / src / org / cacert / gigi / dbObjects / Domain.java
1 package org.cacert.gigi.dbObjects;
2
3 import java.sql.PreparedStatement;
4 import java.sql.ResultSet;
5 import java.sql.SQLException;
6 import java.util.Collections;
7 import java.util.LinkedList;
8 import java.util.List;
9
10 import org.cacert.gigi.GigiApiException;
11 import org.cacert.gigi.database.DatabaseConnection;
12 import org.cacert.gigi.dbObjects.DomainPingConfiguration.PingType;
13
14 public class Domain implements IdCachable {
15
16     public class DomainPingExecution {
17
18         private String state;
19
20         private String type;
21
22         private String info;
23
24         private String result;
25
26         private DomainPingConfiguration config;
27
28         public DomainPingExecution(ResultSet rs) throws SQLException {
29             state = rs.getString(1);
30             type = rs.getString(2);
31             info = rs.getString(3);
32             result = rs.getString(4);
33             config = DomainPingConfiguration.getById(rs.getInt(5));
34         }
35
36         public String getState() {
37             return state;
38         }
39
40         public String getType() {
41             return type;
42         }
43
44         public String getInfo() {
45             return info;
46         }
47
48         public String getResult() {
49             return result;
50         }
51
52         public DomainPingConfiguration getConfig() {
53             return config;
54         }
55
56     }
57
58     private User owner;
59
60     private String suffix;
61
62     private int id;
63
64     private Domain(int id) throws SQLException {
65         PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT memid, domain FROM `domains` WHERE id=? AND deleted IS NULL");
66         ps.setInt(1, id);
67
68         ResultSet rs = ps.executeQuery();
69         if ( !rs.next()) {
70             throw new IllegalArgumentException("Invalid domain id " + id);
71         }
72         this.id = id;
73         owner = User.getById(rs.getInt(1));
74         suffix = rs.getString(2);
75         rs.close();
76     }
77
78     public Domain(User owner, String suffix) throws GigiApiException {
79         this.owner = owner;
80         this.suffix = suffix;
81
82     }
83
84     private static void checkInsert(String suffix) throws GigiApiException {
85         try {
86             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT 1 FROM `domains` WHERE (domain=RIGHT(?,LENGTH(domain))  OR RIGHT(domain,LENGTH(?))=?) AND deleted IS NULL");
87             ps.setString(1, suffix);
88             ps.setString(2, suffix);
89             ps.setString(3, suffix);
90             ResultSet rs = ps.executeQuery();
91             boolean existed = rs.next();
92             rs.close();
93             if (existed) {
94                 throw new GigiApiException("Domain could not be inserted. Domain is already valid.");
95             }
96         } catch (SQLException e) {
97             throw new GigiApiException(e);
98         }
99     }
100
101     public void insert() throws GigiApiException {
102         if (id != 0) {
103             throw new GigiApiException("already inserted.");
104         }
105         synchronized (Domain.class) {
106             checkInsert(suffix);
107             try {
108                 PreparedStatement ps = DatabaseConnection.getInstance().prepare("INSERT INTO `domains` SET memid=?, domain=?");
109                 ps.setInt(1, owner.getId());
110                 ps.setString(2, suffix);
111                 ps.execute();
112                 id = DatabaseConnection.lastInsertId(ps);
113                 myCache.put(this);
114             } catch (SQLException e) {
115                 throw new GigiApiException(e);
116             }
117         }
118     }
119
120     public void delete() throws GigiApiException {
121         if (id == 0) {
122             throw new GigiApiException("not inserted.");
123         }
124         try {
125             PreparedStatement ps = DatabaseConnection.getInstance().prepare("UPDATE `domains` SET deleted=CURRENT_TIMESTAMP WHERE id=?");
126             ps.setInt(1, id);
127             ps.execute();
128         } catch (SQLException e) {
129             throw new GigiApiException(e);
130         }
131     }
132
133     public User getOwner() {
134         return owner;
135     }
136
137     @Override
138     public int getId() {
139         return id;
140     }
141
142     public String getSuffix() {
143         return suffix;
144     }
145
146     private LinkedList<DomainPingConfiguration> configs = null;
147
148     public List<DomainPingConfiguration> getConfiguredPings() throws GigiApiException {
149         LinkedList<DomainPingConfiguration> configs = this.configs;
150         if (configs == null) {
151             try {
152                 configs = new LinkedList<>();
153                 PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id FROM pingconfig WHERE domainid=?");
154                 ps.setInt(1, id);
155                 ResultSet rs = ps.executeQuery();
156                 while (rs.next()) {
157                     configs.add(DomainPingConfiguration.getById(rs.getInt(1)));
158                 }
159                 rs.close();
160                 this.configs = configs;
161             } catch (SQLException e) {
162                 throw new GigiApiException(e);
163             }
164
165         }
166         return Collections.unmodifiableList(configs);
167     }
168
169     public void addPing(PingType ssl, String config) throws GigiApiException {
170         try {
171             PreparedStatement ps = DatabaseConnection.getInstance().prepare("INSERT INTO pingconfig SET domainid=?, type=?, info=?");
172             ps.setInt(1, id);
173             ps.setString(2, ssl.toString().toLowerCase());
174             ps.setString(3, config);
175             ps.execute();
176             configs = null;
177         } catch (SQLException e) {
178             throw new GigiApiException(e);
179         }
180     }
181
182     public void verify(String hash) throws GigiApiException {
183         try {
184             PreparedStatement ps = DatabaseConnection.getInstance().prepare("UPDATE domainPinglog SET state='success' WHERE challenge=? AND configId IN (SELECT id FROM pingconfig WHERE domainId=?)");
185             ps.setString(1, hash);
186             ps.setInt(2, id);
187             ps.executeUpdate();
188         } catch (SQLException e) {
189             throw new GigiApiException(e);
190         }
191     }
192
193     public boolean isVerified() {
194         try {
195             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT 1 FROM domainPinglog INNER JOIN pingconfig ON pingconfig.id=domainPinglog.configId WHERE domainid=? AND state='success'");
196             ps.setInt(1, id);
197             ResultSet rs = ps.executeQuery();
198             return rs.next();
199         } catch (SQLException e) {
200             e.printStackTrace();
201         }
202         return false;
203     }
204
205     public DomainPingExecution[] getPings() throws GigiApiException {
206         try {
207             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT state, type, info, result, configId FROM domainPinglog INNER JOIN pingconfig ON pingconfig.id=domainPinglog.configid WHERE pingconfig.domainid=? ORDER BY `when` DESC;");
208             ps.setInt(1, id);
209             ResultSet rs = ps.executeQuery();
210             rs.last();
211             DomainPingExecution[] contents = new DomainPingExecution[rs.getRow()];
212             rs.beforeFirst();
213             for (int i = 0; i < contents.length && rs.next(); i++) {
214                 contents[i] = new DomainPingExecution(rs);
215             }
216             return contents;
217         } catch (SQLException e) {
218             throw new GigiApiException(e);
219         }
220
221     }
222
223     private static ObjectCache<Domain> myCache = new ObjectCache<>();
224
225     public static synchronized Domain getById(int id) throws IllegalArgumentException {
226         Domain em = myCache.get(id);
227         if (em == null) {
228             try {
229                 myCache.put(em = new Domain(id));
230             } catch (SQLException e1) {
231                 throw new IllegalArgumentException(e1);
232             }
233         }
234         return em;
235     }
236
237 }