/*==========================================================================*\ | $Id: contentAssist.java,v 1.3 2011/12/25 02:24:54 stedwar2 Exp $ |*-------------------------------------------------------------------------*| | Copyright (C) 2006-2011 Virginia Tech | | This file is part of Web-CAT. | | Web-CAT is free software; you can redistribute it and/or modify | it under the terms of the GNU Affero General Public License as published | by the Free Software Foundation; either version 3 of the License, or | (at your option) any later version. | | Web-CAT is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU Affero General Public License | along with Web-CAT; if not, see <http://www.gnu.org/licenses/>. \*==========================================================================*/ package org.webcat.core.actions; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.webcat.core.Application; import org.webcat.core.EntityUtils; import org.webcat.core.KVCAttributeFinder; import org.webcat.core.KVCAttributeInfo; import org.webcat.core.Subsystem; import org.webcat.woextensions.ReadOnlyEditingContext; import com.webobjects.appserver.WOActionResults; import com.webobjects.appserver.WORequest; import com.webobjects.appserver.WOResponse; import com.webobjects.eoaccess.EOEntity; import com.webobjects.eoaccess.EOModel; import com.webobjects.eoaccess.EOModelGroup; import com.webobjects.eoaccess.EOUtilities; import com.webobjects.eocontrol.EOEnterpriseObject; import com.webobjects.eocontrol.EOFetchSpecification; import com.webobjects.eocontrol.EOSortOrdering; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSComparator; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSMutableDictionary; import com.webobjects.foundation.NSComparator.ComparisonException; import er.extensions.appserver.ERXDirectAction; //------------------------------------------------------------------------- /** * A direct action used by the BIRT report designer to request information about * entities and key paths, used for content assistance and previewing purposes. * * @author Tony Allevato * @author Last changed by $Author: stedwar2 $ * @version $Revision: 1.3 $, $Date: 2011/12/25 02:24:54 $ */ public class contentAssist extends ERXDirectAction { //~ Constructor ........................................................... // ---------------------------------------------------------- /** * Creates a new object. * @param request The incoming request */ public contentAssist(WORequest request) { super(request); } //~ Public Methods ........................................................ // ---------------------------------------------------------- /** * An action that returns as its response a list of entities recognized by * Web-CAT and the keys that are valid on them. * * @return the action response */ public WOActionResults entityDescriptionsAction() { WOResponse response = new WOResponse(); int designerVersion = designerVersionFromRequest(); if (designerVersion <= VERSION_1_0_0) { // Use the old-style response. appendEntityDescriptions1_0_0(response); } else { try { appendEntityDescriptions1_1_0(response); } catch (JSONException e) { // Ignore it for now. } } return response; } // ---------------------------------------------------------- private int designerVersionFromRequest() { String versionString = (String) request().formValueForKey("designerVersion"); if (versionString == null) { return 1 * 256 * 256; } else { return Integer.parseInt((String) request().formValueForKey("designerVersion")); } } // ---------------------------------------------------------- private void appendEntityDescriptions1_0_0(WOResponse response) { NSDictionary<String, String> versions = subsystemVersions(); for (String subsystem : versions.allKeys()) { response.appendContentString("version:" + subsystem + "," + versions.objectForKey(subsystem) + "\n"); } for (EOModel model : EOModelGroup.defaultGroup().models()) { for (EOEntity entity : model.entities()) { String className = entity.className(); boolean exclude = false; for (String toExclude : ENTITIES_TO_EXCLUDE) { if (toExclude.equals(className)) { exclude = true; break; } } if (exclude) { continue; } try { Class<?> klass = Class.forName(className); response.appendContentString("entity:" + klass.getSimpleName() + "\n"); NSArray<KVCAttributeInfo> attributes = KVCAttributeFinder.attributesForClass(klass, ""); for (KVCAttributeInfo attr : attributes) { response.appendContentString("attribute:" + attr.name() + "," + attr.type() + "\n"); } } catch (ClassNotFoundException e) { // If, for some reason, the class was not found, just don't // output any keys for it. } } } } // ---------------------------------------------------------- private void appendEntityDescriptions1_1_0(WOResponse response) throws JSONException { NSDictionary<String, String> versions = subsystemVersions(); JSONObject root = new JSONObject(); JSONArray subsystemArray = new JSONArray(); for (String subsystem : versions.allKeys()) { JSONObject subsObj = new JSONObject(); subsObj.put("name", subsystem); subsObj.put("version", versions.objectForKey(subsystem)); subsystemArray.put(subsObj); } root.put("subsystems", subsystemArray); JSONArray entityArray = new JSONArray(); for (EOModel model : EOModelGroup.defaultGroup().models()) { for (EOEntity entity : model.entities()) { String className = entity.className(); boolean exclude = false; for (String toExclude : ENTITIES_TO_EXCLUDE) { if (toExclude.equals(className)) { exclude = true; break; } } if (exclude) { continue; } try { Class<?> klass = Class.forName(className); JSONObject entityObj = new JSONObject(); entityObj.put("name", klass.getSimpleName()); JSONArray attributeArray = new JSONArray(); NSArray<KVCAttributeInfo> attributes = KVCAttributeFinder.attributesForClass(klass, ""); try { attributes = attributes.sortedArrayUsingComparator(new NSComparator() { @Override public int compare(Object _lhs, Object _rhs) throws ComparisonException { KVCAttributeInfo lhs = (KVCAttributeInfo) _lhs; KVCAttributeInfo rhs = (KVCAttributeInfo) _rhs; return lhs.name().compareTo(rhs.name()); } }); } catch (ComparisonException e) { // Do nothing. } for (KVCAttributeInfo attr : attributes) { JSONObject attrObj = new JSONObject(); attrObj.put("name", attr.name()); attrObj.put("type", attr.type()); attrObj.put("properties", new JSONObject(attr.allPropertyValues())); attributeArray.put(attrObj); } entityObj.put("attributes", attributeArray); entityArray.put(entityObj); } catch (ClassNotFoundException e) { // If, for some reason, the class was not found, just don't // output any keys for it. } } } root.put("entities", entityArray); response.appendContentString(root.toString()); } // ---------------------------------------------------------- /** * An action that returns as its response a list of active objects for * various entities in Web-CAT, used to give the user choices when * constructing a preview query in the designer. * * @return the action response */ public WOActionResults objectDescriptionsAction() { WOResponse response = new WOResponse(); int designerVersion = designerVersionFromRequest(); if (designerVersion <= VERSION_1_0_0) { // Use the old-style response. appendObjectDescriptions1_0_0(response); } else { try { appendObjectDescriptions1_1_0(response); } catch (JSONException e) { // Ignore it for now. } } return response; } // ---------------------------------------------------------- public void appendObjectDescriptions1_0_0(WOResponse response) { ReadOnlyEditingContext ec = ReadOnlyEditingContext.newEditingContext(); try { ec.lock(); for (String entityName : OBJECTS_TO_DESCRIBE) { NSArray<EOSortOrdering> orderings = EntityUtils.sortOrderingsForEntityNamed(entityName); EOFetchSpecification fetchSpec = new EOFetchSpecification( entityName, null, orderings); fetchSpec.setFetchLimit(250); @SuppressWarnings("unchecked") NSArray<EOEnterpriseObject> objects = ec.objectsWithFetchSpecification(fetchSpec); response.appendContentString("entity:" + entityName + "\n"); for (EOEnterpriseObject object : objects) { Number id = (Number)EOUtilities.primaryKeyForObject( ec, object).objectForKey( "id" ); response.appendContentString("object:" + id.toString() + "," + object.toString() + "\n"); } } } finally { ec.unlock(); ec.dispose(); } } // ---------------------------------------------------------- public void appendObjectDescriptions1_1_0(WOResponse response) throws JSONException { ReadOnlyEditingContext ec = ReadOnlyEditingContext.newEditingContext(); try { ec.lock(); JSONObject root = new JSONObject(); JSONArray entityArray = new JSONArray(); for (String entityName : OBJECTS_TO_DESCRIBE) { NSArray<EOSortOrdering> orderings = EntityUtils.sortOrderingsForEntityNamed(entityName); EOFetchSpecification fetchSpec = new EOFetchSpecification( entityName, null, orderings); fetchSpec.setFetchLimit(250); @SuppressWarnings("unchecked") NSArray<EOEnterpriseObject> objects = ec.objectsWithFetchSpecification(fetchSpec); JSONObject entityObj = new JSONObject(); entityObj.put("name", entityName); JSONArray objectArray = new JSONArray(); for (EOEnterpriseObject object : objects) { Number id = (Number)EOUtilities.primaryKeyForObject( ec, object).objectForKey( "id" ); JSONObject objectObj = new JSONObject(); objectObj.put("id", id.intValue()); objectObj.put("representation", object.toString()); objectArray.put(objectObj); } entityObj.put("objects", objectArray); entityArray.put(entityObj); } root.put("entities", entityArray); response.appendContentString(root.toString()); } finally { ec.unlock(); ec.dispose(); } } // ---------------------------------------------------------- /** * An action that returns as its response a list of the subsystems installed * in this instance of Web-CAT and their versions. * * @return the action response */ public WOActionResults subsystemVersionCheckAction() { WOResponse response = new WOResponse(); NSDictionary<String, String> versions = subsystemVersions(); for (String subsystem : versions.allKeys()) { response.appendContentString("version:" + subsystem + "," + versions.objectForKey(subsystem) + "\n"); } return response; } //~ Private Methods ....................................................... // ---------------------------------------------------------- /** * Gets a dictionary whose keys are the names of the subsystems in this * instance of Web-CAT and values are their versions. * * @return a dictionary containing the subsystem version information */ private NSDictionary<String, String> subsystemVersions() { NSMutableDictionary<String, String> subsystemVersions = new NSMutableDictionary<String, String>(); NSArray<Subsystem> subsystems = Application.wcApplication() .subsystemManager().subsystems(); for (Subsystem subsystem : subsystems) { for (String nameToCheck : SUBSYSTEMS_TO_CHECK) { if (nameToCheck.equals(subsystem.name())) { subsystemVersions.setObjectForKey( subsystem.descriptor().currentVersion(), nameToCheck); break; } } } return subsystemVersions; } //~ Instance/static variables ............................................. private static final int VERSION_1_0_0 = 256 * 256; @SuppressWarnings("unused") private static final int VERSION_1_1_0 = 256 * 256 + 256; private static final String[] ENTITIES_TO_EXCLUDE = { "CoreSelections", "ERXGenericRecord", "GraderPrefs", "LoginSession", "PasswordChangeRequest" }; private static final String[] OBJECTS_TO_DESCRIBE = { "Assignment", "AssignmentOffering", "AuthenticationDomain", "Course", "CourseOffering", "Department", "Semester" }; private static final String[] SUBSYSTEMS_TO_CHECK = { "BatchProcessor", "Core", "Grader", "Reporter" }; }