
org.bridje.web.view.WebViewsManager Maven / Gradle / Ivy
/*
* Copyright 2016 Bridje Framework.
*
* 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 org.bridje.web.view;
import org.bridje.web.i18n.WebI18nServices;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.el.ELException;
import javax.xml.bind.annotation.XmlTransient;
import org.bridje.el.ElEnvironment;
import org.bridje.el.ElService;
import org.bridje.http.HttpBridletContext;
import org.bridje.http.HttpBridletRequest;
import org.bridje.http.HttpBridletResponse;
import org.bridje.http.HttpException;
import org.bridje.ioc.Component;
import org.bridje.ioc.Inject;
import org.bridje.ioc.IocContext;
import org.bridje.ioc.thls.Thls;
import org.bridje.ioc.thls.ThlsAction;
import org.bridje.vfs.GlobExpr;
import org.bridje.vfs.Path;
import org.bridje.vfs.VFile;
import org.bridje.web.RedirectTo;
import org.bridje.web.ReqPathRef;
import org.bridje.web.WebScope;
import org.bridje.web.view.controls.ControlInputReader;
import org.bridje.web.view.controls.ControlManager;
import org.bridje.web.view.controls.UIEvent;
import org.bridje.web.view.state.StateManager;
import org.bridje.web.view.themes.ThemesManager;
/**
* A manager for all the web views present in the application. with this
* component you can get access to the list of web views that the current
* application has.
*/
@Component
@XmlTransient
public class WebViewsManager
{
private static final Logger LOG = Logger.getLogger(WebViewsManager.class.getName());
@Inject
private ControlManager controlManag;
@Inject
private ThemesManager themesMang;
@Inject
private ElService elServ;
@Inject
private StateManager stateManag;
@Inject
private WebLayoutManager layoutManag;
@Inject
private WebI18nServices webI18nServ;
private Map views;
private final Path basePath = new Path("/web");
/**
* IoC init method do not call this manually.
*/
@PostConstruct
public void init()
{
initViews();
}
/**
* Finds the view by the given path.
*
* @param path The web view path to be found.
*
* @return The web view founded or null if it does not exists.
*/
public WebView findView(String path)
{
return views.get(path);
}
/**
* Finds the view by the requested path of the given HTTP bridlet context.
*
* @param context The current HTTP bridlet context to extract the path of
* the view.
*
* @return The web view founded or null if it does not exists.
*/
public WebView findView(HttpBridletContext context)
{
String viewName = findViewName(context);
return findView(viewName);
}
/**
* Finds the view to be updated by the Bridje-View header sended to the
* server.
*
* @param context The current HTTP bridlet context to extract the path of
* the view.
*
* @return The web view if the header Bridje-View was send to the server, null
* otherwise.
*
* @throws org.bridje.http.HttpException If the Bridje-View parameter was send
* but the view referenced by it does
* not exists.
*/
public WebView findUpdateView(HttpBridletContext context) throws HttpException
{
String viewName = findUpdateViewName(context);
if (viewName != null)
{
WebView view = findView(viewName);
if (view == null)
{
throw new HttpException(400, "Bad Request");
}
return view;
}
return null;
}
/**
* Finds if there is a view to be updated by the Bridje-View header name sended to
* the server.
*
* @param context The current HTTP bridlet context to extract the path of
* the view.
*
* @return The current request is a view update request.
*/
public boolean isUpdateView(HttpBridletContext context)
{
return findUpdateViewName(context) != null;
}
/**
* Base path for all views.
*
* @return The base path for all views.
*/
public Path getBasePath()
{
return basePath;
}
/**
* Finds the name of the view to be updated by the Bridje-View header name sended
* to the server.
*
* @param context The current HTTP bridlet context to extract the path of
* the view.
*
* @return The name of the web view if the header Bridje-View was send to the
* server, null otherwise.
*/
public String findUpdateViewName(HttpBridletContext context)
{
HttpBridletRequest req = context.getRequest();
String viewUpdate = req.getHeader("Bridje-View");
if (viewUpdate != null && !viewUpdate.isEmpty())
{
return viewUpdate;
}
return null;
}
/**
* Renders the given web view to the response output stream.
*
* @param view The view to render.
* @param context The HTTP bridlet context for the current request.
* @param params The parameters that can be accessed within the view.
*/
public void renderView(WebView view, HttpBridletContext context, Map params)
{
if(view == null) return;
IocContext wrsCtx = context.get(IocContext.class);
HttpBridletResponse resp = context.getResponse();
try (OutputStream os = resp.getOutputStream())
{
ElEnvironment elEnv = elServ.createElEnvironment(wrsCtx);
elEnv.pushVar("view", view);
elEnv.pushVar("i18n", webI18nServ.getI18nMap());
elEnv.pushVar("params", params);
elEnv.pushVar("eventResult", EventResult.none());
Thls.doAsEx(() ->
{
themesMang.render(view, os, () -> stateManag.createViewState(wrsCtx));
os.flush();
return null;
}, ElEnvironment.class, elEnv);
}
catch (Exception ex)
{
LOG.log(Level.SEVERE, ex.getMessage(), ex);
}
}
/**
* Renders the given web view to the response output stream.
*
* @param view The view to render.
* @param context The HTTP bridlet context for the current request.
*/
public void renderView(WebView view, HttpBridletContext context)
{
IocContext wrsCtx = context.get(IocContext.class);
HttpBridletResponse resp = context.getResponse();
try (OutputStream os = resp.getOutputStream())
{
ElEnvironment elEnv = elServ.createElEnvironment(wrsCtx);
elEnv.pushVar("view", view);
elEnv.pushVar("i18n", webI18nServ.getI18nMap());
elEnv.pushVar("eventResult", EventResult.none());
Thls.doAsEx(() ->
{
themesMang.render(view, os, () -> stateManag.createViewState(wrsCtx));
os.flush();
return null;
}, ElEnvironment.class, elEnv);
}
catch (Exception ex)
{
LOG.log(Level.SEVERE, ex.getMessage(), ex);
}
}
/**
* Performs a view update and/or an event invocation by the data sended to
* the server in the given request.
*
* @param view The view to be updated.
* @param context The HTTP bridlet context for the current request.
*/
public void updateView(WebView view, HttpBridletContext context)
{
IocContext wrsCtx = context.get(IocContext.class);
HttpBridletRequest req = context.getRequest();
ElEnvironment elEnv = elServ.createElEnvironment(wrsCtx);
Thls.doAs(() ->
{
view.getRoot().readInput(new ControlInputReader(req), elEnv);
EventResult result = view.getRoot().executeEvent(new ControlInputReader(req), elEnv);
if(result == null) result = EventResult.none();
if(result.getData() != null && result.getData() instanceof RedirectTo)
{
RedirectTo redirectTo = (RedirectTo)result.getData();
context.getResponse().setHeader("Bridje-Location", redirectTo.getResource());
}
else
{
elEnv.pushVar("view", view);
elEnv.pushVar("i18n", webI18nServ.getI18nMap());
elEnv.pushVar("eventResult", result);
HttpBridletResponse resp = context.getResponse();
try (OutputStream os = resp.getOutputStream())
{
themesMang.render(view.getRoot(), view, os, result, () -> stateManag.createViewState(wrsCtx));
os.flush();
}
catch (IOException ex)
{
LOG.log(Level.SEVERE, ex.getMessage(), ex);
}
}
return null;
}, ElEnvironment.class, elEnv);
}
/**
* Renders the given web view partially, (as the result of an update) to the response output stream.
*
* @param view The view to render.
* @param context The HTTP bridlet context for the current request.
* @param result The event result for this render operation.
* @param params The parameters that can be accessed within the view.
*/
public void renderPartialView(WebView view, HttpBridletContext context, EventResult result, Map params)
{
IocContext wrsCtx = context.get(IocContext.class);
try
{
ElEnvironment elEnv = elServ.createElEnvironment(wrsCtx);
Thls.doAsEx(() ->
{
elEnv.pushVar("view", view);
elEnv.pushVar("i18n", webI18nServ.getI18nMap());
elEnv.pushVar("params", params);
elEnv.pushVar("eventResult", result);
HttpBridletResponse resp = context.getResponse();
try (OutputStream os = resp.getOutputStream())
{
themesMang.render(view.getRoot(), view, os, result, () -> stateManag.createViewState(wrsCtx));
os.flush();
}
return null;
}, ElEnvironment.class, elEnv);
}
catch (Exception ex)
{
LOG.log(Level.SEVERE, ex.getMessage(), ex);
}
}
/**
* Finds the name of the view to be rendered by the path of the HTTP
* request.
*
* @param context The HTTP bridlet context to get the path form.
*
* @return The name of the view to be use to render this request.
*/
public String findViewName(HttpBridletContext context)
{
WebViewRef viewRef = context.get(WebViewRef.class);
if (viewRef != null && viewRef.getViewPath() != null)
{
return viewRef.getViewPath();
}
return "/public" + ReqPathRef.findCurrentPath(context);
}
private void initViews()
{
views = new HashMap<>();
VFile publicFolder = new VFile(basePath);
if (publicFolder.isDirectory())
{
GlobExpr exp = new GlobExpr("**.view.xml");
VFile[] files = publicFolder.search(exp);
Arrays.asList(files).forEach(this::readView);
}
}
private void readView(VFile f)
{
try
{
WebView view = controlManag.read(f, WebView.class);
if (view != null)
{
view.setFile(f);
updateViewMetaTags(view);
views.put(view.getName(), view);
}
}
catch (IOException e)
{
LOG.log(Level.SEVERE, "Could not parse " + f.getPath() + ". " + e.getMessage(), e);
}
}
private void updateViewMetaTags(WebView view)
{
if (!(view.getDefinition() instanceof ExtendsFrom))
{
return;
}
String layout = ((ExtendsFrom) view.getDefinition()).getLayout();
WebLayout webLayout = layoutManag.loadLayout(view, layout);
if (webLayout != null)
{
view.updateMetaTags(webLayout.getMetaTags());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy