Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.ambari.server.view; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.persist.Transactional; import org.apache.ambari.server.orm.entities.PermissionEntity; import org.apache.ambari.server.orm.entities.ViewEntity; import org.apache.ambari.server.orm.entities.ViewInstanceEntity; import org.apache.ambari.server.view.configuration.ParameterConfig; import org.apache.ambari.server.view.configuration.ViewConfig; import org.apache.ambari.server.view.events.EventImpl; import org.apache.ambari.server.view.persistence.DataStoreImpl; import org.apache.ambari.server.view.persistence.DataStoreModule; import org.apache.ambari.server.view.validation.ValidationException; import org.apache.ambari.view.AmbariStreamProvider; import org.apache.ambari.view.DataStore; import org.apache.ambari.view.ImpersonatorSetting; import org.apache.ambari.view.MaskException; import org.apache.ambari.view.Masker; import org.apache.ambari.view.ResourceProvider; import org.apache.ambari.view.SecurityException; import org.apache.ambari.view.SystemException; import org.apache.ambari.view.ViewContext; import org.apache.ambari.view.ViewController; import org.apache.ambari.view.ViewDefinition; import org.apache.ambari.view.ViewInstanceDefinition; import org.apache.ambari.view.events.Event; import org.apache.ambari.view.events.Listener; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.ParseErrorException; import java.io.StringWriter; import java.io.Writer; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; /** * View context implementation. */ public class ViewContextImpl implements ViewContext, ViewController { /** * Logger. */ private static final Log LOG = LogFactory.getLog(ViewContextImpl.class); /** * The associated view definition. */ private final ViewEntity viewEntity; /** * The associated view definition. */ private final ViewInstanceEntity viewInstanceEntity; /** * The view registry. */ private final ViewRegistry viewRegistry; /** * The URL stream provider. */ private ViewURLStreamProvider streamProvider; /** * The Ambari stream provider. */ private ViewAmbariStreamProvider ambariStreamProvider; /** * The data store. */ private DataStore dataStore = null; /** * Masker for properties. */ private Masker masker; private final VelocityContext velocityContext; // ---- Constructors ------------------------------------------------------- /** * Construct a view context from the given view instance entity. * * @param viewInstanceEntity the view entity * @param viewRegistry the view registry */ public ViewContextImpl(ViewInstanceEntity viewInstanceEntity, ViewRegistry viewRegistry) { this(viewInstanceEntity.getViewEntity(), viewInstanceEntity, viewRegistry); } /** * Construct a view context from the given view entity. * * @param viewEntity the view entity * @param viewRegistry the view registry */ public ViewContextImpl(ViewEntity viewEntity, ViewRegistry viewRegistry) { this(viewEntity, null, viewRegistry); } private ViewContextImpl(ViewEntity viewEntity, ViewInstanceEntity viewInstanceEntity, ViewRegistry viewRegistry) { this.viewEntity = viewEntity; this.viewInstanceEntity = viewInstanceEntity; this.viewRegistry = viewRegistry; this.masker = getMasker(viewEntity.getClassLoader(), viewEntity.getConfiguration()); this.velocityContext = initVelocityContext(); } // ----- ViewContext ------------------------------------------------------- @Override public String getViewName() { return viewEntity.getCommonName(); } @Override public ViewDefinition getViewDefinition() { return viewEntity; } @Override public String getInstanceName() { return viewInstanceEntity == null ? null : viewInstanceEntity.getName(); } @Override public ViewInstanceDefinition getViewInstanceDefinition() { return viewInstanceEntity; } @Override public Map<String, String> getProperties() { if (viewInstanceEntity == null) { return null; } else { Map<String, String> properties = viewInstanceEntity.getPropertyMap(); // unmasking for (Entry<String, String> entry : properties.entrySet()) { ParameterConfig parameterConfig = null; for (ParameterConfig paramConfig : viewEntity.getConfiguration().getParameters()) { if (StringUtils.equals(paramConfig.getName(), entry.getKey())) { parameterConfig = paramConfig; break; } } if (parameterConfig == null || !parameterConfig.isMasked()) { properties.put(entry.getKey(), entry.getValue()); } else { try { properties.put(entry.getKey(), masker.unmask(entry.getValue())); } catch (MaskException e) { LOG.error("Failed to unmask view property", e); } } } // parametrizing String rawValue; for (String key : properties.keySet()) { rawValue = properties.get(key); try { properties.put(key, parameterize(rawValue)); } catch (ParseErrorException ex) { LOG.warn(String.format("Error during parsing '%s' parameter. Leaving original value.", key)); } } return Collections.unmodifiableMap(properties); } } @Transactional @Override public void putInstanceData(String key, String value) { checkInstance(); ViewInstanceEntity updateInstance = viewRegistry.getViewInstanceEntity(viewInstanceEntity.getViewName(), viewInstanceEntity.getInstanceName()); if (updateInstance != null) { updateInstance.putInstanceData(key, value); try { viewRegistry.updateViewInstance(updateInstance); } catch (SystemException e) { String msg = "Caught exception updating the view instance."; LOG.error(msg, e); throw new IllegalStateException(msg, e); } catch (ValidationException e) { throw new IllegalArgumentException(e.getMessage()); } } } @Override public String getInstanceData(String key) { return viewInstanceEntity == null ? null : viewInstanceEntity.getInstanceDataMap().get(key); } @Override public Map<String, String> getInstanceData() { return viewInstanceEntity == null ? null : Collections.unmodifiableMap(viewInstanceEntity.getInstanceDataMap()); } @Override public void removeInstanceData(String key) { checkInstance(); viewRegistry.removeInstanceData(viewInstanceEntity, key); } @Override public String getAmbariProperty(String key) { return viewInstanceEntity == null ? null : viewInstanceEntity.getViewEntity().getAmbariProperty(key); } @Override public ResourceProvider<?> getResourceProvider(String type) { return viewInstanceEntity == null ? null : viewInstanceEntity.getResourceProvider(type); } @Override public String getUsername() { return viewInstanceEntity != null ? viewInstanceEntity.getUsername() : null; } @Override public void hasPermission(String userName, String permissionName) throws org.apache.ambari.view.SecurityException { if (userName == null || userName.length() == 0) { throw new SecurityException("No user name specified."); } if (permissionName == null || permissionName.length() == 0) { throw new SecurityException("No permission name specified."); } if (viewInstanceEntity == null) { throw new SecurityException("There is no instance associated with the view context"); } PermissionEntity permissionEntity = viewEntity.getPermission(permissionName); if (permissionEntity == null) { throw new SecurityException( "The permission " + permissionName + " is not defined for " + viewEntity.getName()); } if (!viewRegistry.hasPermission(permissionEntity, viewInstanceEntity.getResource(), userName)) { throw new SecurityException( "The user " + userName + " has not been granted permission " + permissionName); } } @Override public org.apache.ambari.view.URLStreamProvider getURLStreamProvider() { ensureURLStreamProvider(); return streamProvider; } @Override public synchronized AmbariStreamProvider getAmbariStreamProvider() { if (ambariStreamProvider == null) { ambariStreamProvider = viewRegistry.createAmbariStreamProvider(); } return ambariStreamProvider; } @Override public synchronized DataStore getDataStore() { if (viewInstanceEntity != null) { if (dataStore == null) { Injector injector = Guice.createInjector(new DataStoreModule(viewInstanceEntity)); dataStore = injector.getInstance(DataStoreImpl.class); } } return dataStore; } @Override public Collection<ViewDefinition> getViewDefinitions() { return Collections.<ViewDefinition>unmodifiableCollection(viewRegistry.getDefinitions()); } @Override public Collection<ViewInstanceDefinition> getViewInstanceDefinitions() { Collection<ViewInstanceEntity> instanceDefinitions = new HashSet<ViewInstanceEntity>(); for (ViewEntity viewEntity : viewRegistry.getDefinitions()) { instanceDefinitions.addAll(viewRegistry.getInstanceDefinitions(viewEntity)); } return Collections.<ViewInstanceDefinition>unmodifiableCollection(instanceDefinitions); } @Override public ViewController getController() { return this; } @Override public HttpImpersonatorImpl getHttpImpersonator() { ensureURLStreamProvider(); return new HttpImpersonatorImpl(this); } @Override public ImpersonatorSetting getImpersonatorSetting() { return new ImpersonatorSettingImpl(this); } // ----- ViewController ---------------------------------------------------- @Override public void fireEvent(String eventId, Map<String, String> eventProperties) { Event event = viewInstanceEntity == null ? new EventImpl(eventId, eventProperties, viewEntity) : new EventImpl(eventId, eventProperties, viewInstanceEntity); viewRegistry.fireEvent(event); } @Override public void registerListener(Listener listener, String viewName) { viewRegistry.registerListener(listener, viewName, null); } @Override public void registerListener(Listener listener, String viewName, String viewVersion) { viewRegistry.registerListener(listener, viewName, viewVersion); } @Override public void unregisterListener(Listener listener, String viewName) { viewRegistry.unregisterListener(listener, viewName, null); } @Override public void unregisterListener(Listener listener, String viewName, String viewVersion) { viewRegistry.unregisterListener(listener, viewName, viewVersion); } // ----- helper methods ---------------------------------------------------- // ensure that the URL stream provider has been created private synchronized void ensureURLStreamProvider() { if (streamProvider == null) { streamProvider = viewRegistry.createURLStreamProvider(this); } } // check for an associated instance private void checkInstance() { if (viewInstanceEntity == null) { throw new IllegalStateException("No instance is associated with the context."); } } private Masker getMasker(ClassLoader cl, ViewConfig viewConfig) { try { return viewConfig.getMaskerClass(cl).newInstance(); } catch (Exception e) { throw new InstantiationError("Could not create masker instance."); } } /** * Parameterize string using VelocityContext instance * * @param raw original string with parameters in formal or shorthand notation * * @return parameterized string * * @throws ParseErrorException if original string cannot be parsed by Velocity */ private String parameterize(String raw) throws ParseErrorException { if (raw != null) { Writer templateWriter = new StringWriter(); Velocity.evaluate(velocityContext, templateWriter, raw, raw); return templateWriter.toString(); } return null; } /** * Instantiate and initialize context for parameters processing using Velocity. * * @return initialized context instance */ private VelocityContext initVelocityContext() { VelocityContext context = new VelocityContext(); context.put("username", new ParameterResolver() { @Override protected String getValue() { return viewContext.getUsername(); } }); context.put("viewName", new ParameterResolver() { @Override protected String getValue() { return viewContext.getViewName(); } }); context.put("instanceName", new ParameterResolver() { @Override protected String getValue() { return viewContext.getInstanceName(); } }); return context; } // ----- Inner class : ParameterResolver ------------------------------- /** * Represents basic parameter resolver to obtain fields of ViewContext at runtime. */ private abstract class ParameterResolver { protected final ViewContext viewContext = ViewContextImpl.this; protected abstract String getValue(); @Override public String toString() { String value = getValue(); return value == null ? "" : value; } } }