1 /*
   2  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 // Compiled and invoked by remrepo.sh
  27 
  28 import java.io.*;
  29 import java.util.*;
  30 import java.lang.module.*;
  31 import java.net.*;
  32 import org.openjdk.jigsaw.*;
  33 
  34 import static java.lang.System.out;
  35 
  36 public class _RemoteRepository {
  37 
  38     private static ModuleSystem ms = ModuleSystem.base();
  39 
  40     private static <T> boolean equals(Collection<T> c1, Collection<T> c2) {
  41         if (c1 == null)
  42             return c2 == null;
  43         if (c2 == null)
  44             return false;
  45         return c1.containsAll(c2) && c2.containsAll(c1);
  46     }
  47 
  48     private static boolean equals(ModuleInfo mi1, ModuleInfo mi2) {
  49         // ## TODO multiple views
  50         return (mi1.id().equals(mi2.id())
  51                 && mi1.requiresModules().equals(mi2.requiresModules())
  52                 && mi1.requiresServices().equals(mi2.requiresServices())
  53                 && equals(mi1.defaultView(), mi2.defaultView()));
  54     }
  55 
  56     private static boolean equals(ModuleView mv1, ModuleView mv2) {
  57         return (mv1.id().equals(mv2.id())
  58                 && mv1.aliases().equals(mv2.aliases())
  59                 && mv1.services().equals(mv2.services())
  60                 && mv1.permits().equals(mv2.permits())
  61                 && ((mv1.mainClass() == mv2.mainClass())
  62                     || (mv1.mainClass() != null
  63                         && mv1.mainClass().equals(mv2.mainClass()))));
  64     }
  65     
  66     static final File REM_REPO = new File("z.remote");
  67 
  68     static Set<ModuleId> mids = null;
  69 
  70     static byte[] readStream(InputStream in)
  71         throws Exception
  72     {
  73         ByteArrayOutputStream out = new ByteArrayOutputStream();
  74         byte[] buf = new byte[8192];
  75         int n = 0;
  76         while ((n = in.read(buf)) > 0)
  77             out.write(buf, 0, n);
  78         return out.toByteArray();
  79     }
  80 
  81     static boolean equals(InputStream ia, InputStream ib)
  82         throws Exception
  83     {
  84         return Arrays.equals(readStream(ia), readStream(ib));
  85     }
  86 
  87     private static void check(RemoteRepository rr, PublishedRepository pr)
  88         throws Exception
  89     {
  90         assert equals(rr.listModuleIds(), mids)
  91             : String.format("%s : %s", rr.listModuleIds(), mids);
  92         assert equals(pr.listModuleIds(), mids)
  93             : String.format("%s : %s", pr.listModuleIds(), mids);
  94         out.format("Module ids: %s%n", mids);
  95         for (ModuleId mid : mids) {
  96             assert equals(rr.readModuleInfo(mid),
  97                           pr.readModuleInfo(mid));
  98             assert equals(rr.fetch(mid), pr.fetch(mid));
  99         }
 100     }
 101 
 102     static void testRemove(RemoteRepository rr, PublishedRepository pr)
 103         throws Exception
 104     {
 105         check(rr, pr);
 106         ModuleId mid = mids.iterator().next();
 107         mids.remove(mid);
 108         // Ensure time stamp of catelog after removal is at least one second >
 109         // This is the minimum increment represented by the Last-modified header
 110         Thread.sleep(2000);
 111         pr.remove(mid);
 112         rr.updateCatalog(false);
 113         check(rr, pr);
 114     }
 115 
 116     static void test(int port) throws Exception {
 117 
 118         URI u = URI.create("http://localhost:" + port);
 119 
 120         RemoteRepository rr = RemoteRepository.create(REM_REPO, u);
 121         out.format("Remote %s %s%n", REM_REPO, u);
 122 
 123         assert rr.isCatalogStale();
 124         assert rr.updateCatalog(false);
 125         assert !rr.isCatalogStale();
 126         assert !rr.updateCatalog(false);
 127         assert rr.updateCatalog(true);
 128 
 129         PublishedRepository pr = _PublishedRepository.open();
 130 
 131         testRemove(rr, pr);
 132         rr = RemoteRepository.open(REM_REPO);
 133         testRemove(rr, pr);
 134 
 135     }
 136 
 137     public static void main(String[] args)
 138         throws Exception
 139     {
 140         _PublishedRepository.create();
 141         mids = _PublishedRepository.add(args, true);
 142         TrivialWebServer tws
 143             = TrivialWebServer.create(_PublishedRepository.REPO, out);
 144         out.format("Port %d%n", tws.port());
 145         try {
 146             test(tws.port());
 147         } finally {
 148             tws.stop();
 149         }
 150     }
 151 
 152 }