2 * WoTNS - Resolver.java - Copyright © 2011 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.wotns.main;
20 import java.net.MalformedURLException;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.List;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
29 import net.pterodactylus.util.logging.Logging;
30 import net.pterodactylus.util.object.Default;
31 import net.pterodactylus.wotns.freenet.wot.Identity;
32 import net.pterodactylus.wotns.freenet.wot.IdentityManager;
33 import net.pterodactylus.wotns.freenet.wot.OwnIdentity;
34 import net.pterodactylus.wotns.freenet.wot.Trust;
35 import freenet.keys.FreenetURI;
38 * Resolves short names as given by the user.
40 * Short names generally have the syntax:
43 * identity [ ‘@’ start-of-key ] ‘/’ target [ ‘/’ file-path ]
46 * Because resolving a short name is based on the <i>web</i> of trust, the ID of
47 * an own identity must be given in order to find the entry point into the web
48 * of trust. If no ID is specified, the ID of a random own identity is used. If
49 * no own identity exists, short names can not be resolved.
51 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
53 public class Resolver {
56 private static final Logger logger = Logging.getLogger(Resolver.class);
58 /** The identity manager. */
59 private final IdentityManager identityManager;
61 /** The ID of the own identity to use for resolving. */
62 private String ownIdentityId;
65 * Creates a new resolver.
67 * @param identityManager
68 * The identity manager to use
70 public Resolver(IdentityManager identityManager) {
71 this.identityManager = identityManager;
79 * Returns the ID of the own identity used for resolving short names.
81 * @return The ID of the own identity used for resolving
83 public String getOwnIdentityId() {
88 * Sets the ID of the own identity used for resolving short names.
90 * @param ownIdentityId
91 * The ID of the own identity used for resolving
93 public void setOwnIdentityId(String ownIdentityId) {
94 this.ownIdentityId = ownIdentityId;
102 * Resolves a short name.
105 * The short name to resolve
106 * @return The Freenet URI the short name resolves to, or {@code null} if
107 * the short name can not be resolved
108 * @throws MalformedURLException
109 * if the short name is malformed
111 public FreenetURI resolveURI(String shortUri) throws MalformedURLException {
112 int firstSlash = shortUri.indexOf('/');
113 if (firstSlash == -1) {
114 throw new MalformedURLException("At least one slash is required.");
116 String shortName = shortUri.substring(0, firstSlash);
117 String target = shortUri.substring(firstSlash + 1);
118 Identity identity = locateIdentity(shortName);
119 System.out.println("located identity: " + identity);
120 if (identity == null) {
123 return new FreenetURI(identity.getProperty("tns." + target));
131 * Locates the identity specified by the given short name. If more than one
132 * identity matches the given pattern, the one with the highest trust is
133 * used. When calculating the trust, local and remote trust are treated
134 * equally, i.e. the higher value of either one is used.
137 * The short name to locate an identity for
138 * @return The located identity, or {@code null} if no identity can be
139 * found, or if no own identity is found to use for locating an
142 private Identity locateIdentity(String shortName) {
143 int atSign = shortName.indexOf('@');
144 String identityName = shortName;
145 String keyStart = "";
147 identityName = shortName.substring(0, atSign);
148 keyStart = shortName.substring(atSign + 1);
150 final OwnIdentity ownIdentity;
151 if (this.ownIdentityId != null) {
152 if (identityManager.getOwnIdentity(this.ownIdentityId) != null) {
153 ownIdentity = identityManager.getOwnIdentity(this.ownIdentityId);
155 ownIdentity = getFirstOwnIdentity();
158 ownIdentity = getFirstOwnIdentity();
160 if (ownIdentity == null) {
161 logger.log(Level.SEVERE, "Can not resolve “" + shortName + "” without a Web of Trust Identity!");
164 System.out.println("using own identity " + ownIdentity + " to resolve " + shortName);
165 Set<Identity> trustedIdentities = Default.forNull(identityManager.getTrustedIdentities(ownIdentity), Collections.<Identity> emptySet());
166 List<Identity> matchingIdentities = new ArrayList<Identity>();
167 System.out.println("checking " + trustedIdentities);
168 for (Identity identity : trustedIdentities) {
169 if (identity.getNickname().equals(identityName) && identity.getId().startsWith(keyStart)) {
170 matchingIdentities.add(identity);
173 if (matchingIdentities.isEmpty()) {
176 Collections.sort(matchingIdentities, new Comparator<Identity>() {
179 public int compare(Identity leftIdentity, Identity rightIdentity) {
180 Trust leftTrust = leftIdentity.getTrust(ownIdentity);
181 Trust rightTrust = rightIdentity.getTrust(ownIdentity);
182 int leftTrustCombined = ((leftTrust.getExplicit() != null) ? leftTrust.getExplicit() : 0) + ((leftTrust.getImplicit() != null) ? leftTrust.getImplicit() : 0);
183 int rightTrustCombined = ((rightTrust.getExplicit() != null) ? rightTrust.getExplicit() : 0) + ((rightTrust.getImplicit() != null) ? rightTrust.getImplicit() : 0);
184 return leftTrustCombined - rightTrustCombined;
187 return matchingIdentities.get(0);
191 * Returns a random own identity from the web of trust.
193 * @return A random own identity from the web of trust, or {@code null} if
194 * the web of trust does not have any own identities
196 private OwnIdentity getFirstOwnIdentity() {
197 Set<OwnIdentity> ownIdentities = identityManager.getAllOwnIdentities();
198 if (!ownIdentities.isEmpty()) {
199 return ownIdentities.iterator().next();