001/**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019package org.apache.james.mailbox.jpa.migrator.command; 020 021import java.util.List; 022 023import javax.persistence.EntityManager; 024import javax.persistence.Query; 025 026import org.apache.james.mailbox.jpa.migrator.exception.JpaMigrateException; 027 028/** 029 * <p> 030 * JIRA IMAP-168 is "mailboxes can't be identified 100% unambiguously using virtual hosting". 031 * 032 * MAILBOX.NAME contains data such as 033 * "#mail.eric@localhost.net" 034 * "#mail.eric@localhost.net.INBOX" 035 * "#mail.eric@localhost.net.INBOX.test" 036 * "#mail.eric@localhost.net.Trash" 037 * 038 * It needs to be splitted into MAILBOX.NAMESPACE | MAILBOX.USER0 | MAILBOX.NAME with 039 * "#mail" | "eric@localhost.net" | "" ==> was created before, but is not used anymore 040 * "#mail" | "eric@localhost.net" | "INBOX" 041 * "#mail" | "eric@localhost.net" | "INBOX.test" 042 * "#mail" | "eric@localhost.net" | "Trash" 043 *</p> 044 * 045 * @link https://issues.apache.org/jira/browse/IMAP-168 046 * 047 */ 048public class IMAP168JpaMigrateCommand implements JpaMigrateCommand { 049 050 /** 051 * @see org.apache.james.mailbox.jpa.migrator.command#migrate(javax.persistence.EntityManager) 052 */ 053 public void migrate(EntityManager em) throws JpaMigrateException { 054 055 JpaMigrateQuery.executeUpdate(em, "ALTER TABLE MAILBOX ADD COLUMN NAMESPACE VARCHAR(255)"); 056 JpaMigrateQuery.executeUpdate(em, "ALTER TABLE MAILBOX ADD COLUMN USER0 VARCHAR(255)"); 057 058 Query query = em.createNativeQuery("SELECT NAME FROM MAILBOX"); 059 060 @SuppressWarnings("unchecked") 061 List<String> nameList = query.getResultList(); 062 System.out.println("getResultList returned a result=" + nameList.size()); 063 for (String name: nameList) { 064 MailboxPath mailboxPath = new MailboxPath(name); 065 System.out.println(mailboxPath); 066 Query update = em.createNativeQuery("UPDATE MAILBOX SET NAMESPACE = ?, USER0 = ?, NAME = ? WHERE NAME = ?"); 067 update.setParameter(1, mailboxPath.namespace); 068 update.setParameter(2, mailboxPath.userName); 069 update.setParameter(3, mailboxPath.mailboxName); 070 update.setParameter(4, name); 071 int resultUpdate = update.executeUpdate(); 072 System.out.println("ExecuteUpdate returned a result=" + resultUpdate); 073 } 074 075 } 076 077 /** 078 * 079 */ 080 private class MailboxPath { 081 082 protected String namespace; 083 protected String userName; 084 protected String mailboxName; 085 086 /** 087 * @param name 088 */ 089 public MailboxPath (String name) { 090 091 if (! name.startsWith("#mail")) { 092 throw new IllegalArgumentException("The name must begin with #private"); 093 } 094 095 namespace = "#mail"; 096 097 name = name.substring(6); 098 099 int atIndex = name.indexOf("@"); 100 int firstDotIndex = name.indexOf(".", atIndex); 101 int secondDotIndex = name.indexOf(".", firstDotIndex + 1); 102 103 if (secondDotIndex > 0) { 104 userName = name.substring(0, secondDotIndex); 105 mailboxName = name.substring(userName.length() + 1); 106 } 107 else { 108 // We don't have a mailbox name... 109 userName = name.substring(0); 110 mailboxName = ""; 111 } 112 113 } 114 115 @Override 116 public String toString() { 117 return "MailboxPath [namespace=" + namespace + 118 ", userName=" + userName + ", mailboxName=" + mailboxName + "]"; 119 } 120 121 } 122 123}