001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.petstore.console;
018
019import static java.nio.charset.StandardCharsets.*;
020
021import java.io.*;
022
023import org.apache.juneau.http.response.*;
024import org.apache.juneau.petstore.console.dev.*;
025import org.apache.juneau.petstore.console.ops.*;
026import org.apache.juneau.petstore.console.orders.*;
027import org.apache.juneau.petstore.console.pets.*;
028import org.apache.juneau.petstore.console.users.*;
029import org.apache.juneau.rest.server.*;
030
031/**
032 * Root of the petstore admin console, mounted at {@code /console} beside the {@code /petstore} API and sharing its
033 * {@link org.apache.juneau.petstore.service.PetStore}.
034 *
035 * <p>
036 * Every page renders through {@code base.ftlh} (the {@code <@console>} chrome and nav tree).
037 *
038 * <h5 class='section'>Example:</h5>
039 * <p class='bjava'>
040 *    <jc>// Mount it in a runner beside the API; both see the same @Bean PetStore.</jc>
041 *    <ja>@Rest</ja>(children={PetStoreResource.<jk>class</jk>, PetstoreConsoleResource.<jk>class</jk>})
042 *    <jk>public class</jk> RootResources <jk>extends</jk> BasicRestServletGroup {
043 *       <ja>@Bean</ja> <jk>public</jk> PetStore petStore() { <jk>return</jk> PetstoreSeed.<jsm>create</jsm>().populate(<jk>new</jk> PetStore()); }
044 *    }
045 * </p>
046 * <p class='bcode'>
047 *    &lt;#-- base.ftlh --&gt;
048 *    &lt;@console brand="Juneau Petstore"&gt;
049 *      &lt;@navigation&gt;&lt;@node id="store" label="Store" href="/console/store"/&gt; ... &lt;/@navigation&gt;
050 *      &lt;@main/&gt;
051 *    &lt;/@console&gt;
052 * </p>
053 */
054@Rest(
055   path="/console",
056   title="Juneau Petstore console",
057   children={
058      StoreRest.class,
059      PetsRest.class,
060      OrdersRest.class,
061      UsersRest.class,
062      OpsRest.class,
063      DevRest.class,
064      AboutRest.class
065   }
066)
067@SuppressWarnings({
068   "java:S110", // Inheritance depth comes from the BasicRestServlet hierarchy, not this page.
069   "resource" // The response writer is owned by the servlet container; Eclipse JDT @Owning warning is by design.
070})
071public class PetstoreConsoleResource extends PetstoreConsolePage {
072
073   private static final long serialVersionUID = 1L;
074
075   /**
076    * {@code GET /console} redirects to the store dashboard.
077    *
078    * @param req The request.
079    * @return A 303 to {@code /console/store}.
080    */
081   @RestGet(path="/")
082   public SeeOther index(RestRequest req) {
083      return new SeeOther().setLocation(req.getUriResolver().resolve("servlet:/store"));
084   }
085
086   /**
087    * Serves {@code petstore.js}, the shared page script {@code base.ftlh} loads after the toolkit on every page.
088    *
089    * @param res The response.
090    * @throws IOException If the bundled script can't be read.
091    */
092   @RestGet(path="/petstore.js")
093   public void script(RestResponse res) throws IOException {
094      try (var in = PetstoreConsoleResource.class.getResourceAsStream("petstore.js")) {
095         if (in == null)
096            throw new IllegalStateException("Missing classpath resource 'petstore.js' beside " + PetstoreConsoleResource.class.getName());
097         res.setContentType("text/javascript;charset=utf-8");
098         res.getWriter().write(new String(in.readAllBytes(), UTF_8));
099      }
100   }
101}