/** * Get the view as configured in the webconfig. Guarantees to return a non-empty non-null list. * * @param type The type we are trying to get a view for. * @param model The data model * @param webConfig The web-configuration. * @param fieldConfigs * @return The list of paths that we can use to construct a query. * @throws UnconfiguredException if the class has not configured view. */ private static List<String> getConfiguredView(ClassDescriptor cld, WebConfig webConfig) throws UnconfiguredException { Collection<String> view = new LinkedHashSet<String>(); // Preserve order and uniqueness. Model m = cld.getModel(); for (FieldConfig fieldConfig : resultConfigs(webConfig, cld)) { try { Path p = new Path(m, cld.getUnqualifiedName() + "." + fieldConfig.getFieldExpr()); // add subpaths of references and roots, attrs themselves, ignore collections. if (p.isRootPath() || p.endIsReference()) { view.addAll(getSubview(webConfig, m, p)); } else if (p.endIsAttribute()) { view.add(p.getNoConstraintsString()); } } catch (PathException e) { LOG.error("Invalid path configured in webconfig for class: " + cld); } } if (view.isEmpty()) { throw new UnconfiguredException(); } return new ArrayList<String>(view); }
/** * Return a Set of PrimaryKeys relevant to a given Source for a ClassDescriptor. The Set contains * all the primary keys that exist on a particular class that are used by the source, without * performing any recursion. The Model.getClassDescriptorsForClass() method is recommended if you * wish for all the primary keys of the class' parents as well. * * @param cld the ClassDescriptor * @param source the Source * @param os the ObjectStore that these PrimaryKeys are used in, for creating indexes * @return a Set of PrimaryKeys */ public static Set<PrimaryKey> getPrimaryKeys(ClassDescriptor cld, Source source, ObjectStore os) { GetPrimaryKeyCacheKey key = new GetPrimaryKeyCacheKey(cld, source); synchronized (getPrimaryKeyCache) { Set<PrimaryKey> keySet = getPrimaryKeyCache.get(key); if (keySet == null) { keySet = new LinkedHashSet<PrimaryKey>(); Properties keys = getKeyProperties(source); if (keys != null) { if (!verifiedSources.contains(source)) { String packageNameWithDot = cld.getName().substring(0, cld.getName().lastIndexOf('.') + 1); LOG.info( "Verifying primary key config for source " + source + ", packageName = " + packageNameWithDot); for (Map.Entry<Object, Object> entry : keys.entrySet()) { String cldName = (String) entry.getKey(); String keyList = (String) entry.getValue(); if (!cldName.contains(".")) { ClassDescriptor iCld = cld.getModel().getClassDescriptorByName(packageNameWithDot + cldName); if (iCld != null) { Map<String, PrimaryKey> map = PrimaryKeyUtil.getPrimaryKeys(iCld); String[] tokens = keyList.split(","); for (int i = 0; i < tokens.length; i++) { String token = tokens[i].trim(); if (map.get(token) == null) { throw new IllegalArgumentException( "Primary key " + token + " for class " + cldName + " required by datasource " + source.getName() + " in " + source.getName() + "_keys.properties is not defined in " + cld.getModel().getName() + "_keyDefs.properties"); } } } else { LOG.warn( "Ignoring entry for " + cldName + " in file " + cld.getModel().getName() + "_keyDefs.properties - not in model!"); } } } verifiedSources.add(source); } Map<String, PrimaryKey> map = PrimaryKeyUtil.getPrimaryKeys(cld); String cldName = TypeUtil.unqualifiedName(cld.getName()); String keyList = (String) keys.get(cldName); if (keyList != null) { String[] tokens = keyList.split(","); for (int i = 0; i < tokens.length; i++) { String token = tokens[i].trim(); if (map.get(token) == null) { throw new IllegalArgumentException( "Primary key " + token + " for class " + cld.getName() + " required by data source " + source.getName() + " in " + source.getName() + "_keys.properties is not defined in " + cld.getModel().getName() + "_keyDefs.properties"); } else { keySet.add(map.get(token)); } } } for (Map.Entry<Object, Object> entry : keys.entrySet()) { String propKey = (String) entry.getKey(); String fieldList = (String) entry.getValue(); int posOfDot = propKey.indexOf('.'); if (posOfDot > 0) { String propCldName = propKey.substring(0, posOfDot); if (cldName.equals(propCldName)) { String keyName = propKey.substring(posOfDot + 1); PrimaryKey pk = new PrimaryKey(keyName, fieldList, cld); if (!keySet.contains(pk)) { keySet.add(pk); if (os instanceof ObjectStoreInterMineImpl) { ObjectStoreInterMineImpl osimi = (ObjectStoreInterMineImpl) os; DatabaseSchema schema = osimi.getSchema(); ClassDescriptor tableMaster = schema.getTableMaster(cld); String tableName = DatabaseUtil.getTableName(tableMaster); List<String> fields = new ArrayList<String>(); for (String field : pk.getFieldNames()) { String colName = DatabaseUtil.generateSqlCompatibleName(field); if (tableMaster.getReferenceDescriptorByName(field, true) != null) { colName += "id"; } fields.add(colName); } String sql = "CREATE INDEX " + tableName + "__" + keyName + " ON " + tableName + " (" + StringUtil.join(fields, ", ") + ")"; System.out.println("Creating index: " + sql); LOG.info("Creating index: " + sql); Connection conn = null; try { conn = osimi.getConnection(); conn.createStatement().execute(sql); } catch (SQLException e) { LOG.warn("Index creation failed", e); } finally { if (conn != null) { osimi.releaseConnection(conn); } } } } } } } } else { throw new IllegalArgumentException( "Unable to find keys for source " + source.getName() + " in file " + source.getName() + "_keys.properties"); } getPrimaryKeyCache.put(key, keySet); } return keySet; } }