| // Copyright (C) 2009 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.gerrit.server; |
| |
| import com.google.gerrit.client.reviewdb.Account; |
| import com.google.gerrit.client.reviewdb.Change; |
| import com.google.gerrit.client.reviewdb.ReviewDb; |
| import com.google.gwtorm.client.OrmException; |
| |
| import org.spearce.jgit.lib.PersonIdent; |
| import org.spearce.jgit.util.Base64; |
| import org.spearce.jgit.util.NB; |
| |
| import java.net.InetAddress; |
| import java.net.InetSocketAddress; |
| import java.net.SocketAddress; |
| |
| public class ChangeUtil { |
| private static int uuidPrefix; |
| private static int uuidSeq; |
| |
| /** |
| * Generate a new unique identifier for change message entities. |
| * |
| * @param db the database connection, used to increment the change message |
| * allocation sequence. |
| * @return the new unique identifier. |
| * @throws OrmException the database couldn't be incremented. |
| */ |
| public static String messageUUID(final ReviewDb db) throws OrmException { |
| final byte[] raw = new byte[8]; |
| fill(raw, db); |
| return Base64.encodeBytes(raw); |
| } |
| |
| public static PersonIdent toPersonIdent(final Account userAccount) { |
| String name = userAccount.getFullName(); |
| if (name == null) { |
| name = userAccount.getPreferredEmail(); |
| } |
| if (name == null) { |
| name = "Anonymous Coward"; |
| } |
| |
| String user = "account-" + userAccount.getId().toString(); |
| String host = "unknown"; |
| return new PersonIdent(name, user + "@" + host); |
| } |
| |
| public static PersonIdent toReflogIdent(final Account userAccount, |
| final SocketAddress remotePeer) { |
| String name = userAccount.getFullName(); |
| if (name == null) { |
| name = userAccount.getPreferredEmail(); |
| } |
| if (name == null) { |
| name = "Anonymous Coward"; |
| } |
| |
| final String userId = "account-" + userAccount.getId().toString(); |
| final String user; |
| if (userAccount.getSshUserName() != null) { |
| user = userAccount.getSshUserName() + "|" + userId; |
| } else { |
| user = userId; |
| } |
| |
| String host = null; |
| if (remotePeer instanceof InetSocketAddress) { |
| final InetSocketAddress sa = (InetSocketAddress) remotePeer; |
| final InetAddress in = sa.getAddress(); |
| if (in != null) { |
| host = in.getCanonicalHostName(); |
| } else { |
| host = sa.getHostName(); |
| } |
| } |
| if (host == null) { |
| host = "unknown"; |
| } |
| |
| return new PersonIdent(name, user + "@" + host); |
| } |
| |
| private static synchronized void fill(byte[] raw, ReviewDb db) |
| throws OrmException { |
| if (uuidSeq == 0) { |
| uuidPrefix = db.nextChangeMessageId(); |
| uuidSeq = Integer.MAX_VALUE; |
| } |
| NB.encodeInt32(raw, 0, uuidPrefix); |
| NB.encodeInt32(raw, 4, uuidSeq--); |
| } |
| |
| public static void updated(final Change c) { |
| c.resetLastUpdatedOn(); |
| computeSortKey(c); |
| } |
| |
| public static void computeSortKey(final Change c) { |
| // The encoding uses minutes since Wed Oct 1 00:00:00 2008 UTC. |
| // We overrun approximately 4,085 years later, so ~6093. |
| // |
| final long lastUpdatedOn = |
| (c.getLastUpdatedOn().getTime() / 1000L) - 1222819200L; |
| final StringBuilder r = new StringBuilder(16); |
| r.setLength(16); |
| formatHexInt(r, 0, (int) (lastUpdatedOn / 60)); |
| formatHexInt(r, 8, c.getId().get()); |
| c.setSortKey(r.toString()); |
| } |
| |
| private static final char[] hexchar = |
| {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', // |
| 'a', 'b', 'c', 'd', 'e', 'f'}; |
| |
| private static void formatHexInt(final StringBuilder dst, final int p, int w) { |
| int o = p + 7; |
| while (o >= p && w != 0) { |
| dst.setCharAt(o--, hexchar[w & 0xf]); |
| w >>>= 4; |
| } |
| while (o >= p) { |
| dst.setCharAt(o--, '0'); |
| } |
| } |
| } |