/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.web.bundle; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import com.opengamma.util.ArgumentChecker; /** * Utility to build a decorated bundle manager for development bundles */ public class DevBundleBuilder { /** * Maximum number of {@code @imports} allowed in IE. */ public static final int MAX_IMPORTS = 31; /** The maximum level 1 size for IE. */ private static final int LEVEL1_SIZE = MAX_IMPORTS * MAX_IMPORTS; /** The maximum level 2 size for IE. */ private static final int LEVEL2_SIZE = MAX_IMPORTS * MAX_IMPORTS * MAX_IMPORTS; /** * The bundle manager. */ private final BundleManager _bundleManager; /** * Creates an instance. * * @param bundleManager the bundle manger not null */ public DevBundleBuilder(BundleManager bundleManager) { ArgumentChecker.notNull(bundleManager, "bundleManager"); _bundleManager = bundleManager; } //------------------------------------------------------------------------- /** * Decorates the original bundle manager with a version for development. * * @return a new bundle manager for development, not null */ public BundleManager getDevBundleManager() { BundleManager devBundleManager = new BundleManager(); Set<String> bundleNames = _bundleManager.getBundleIds(); for (String bundleId : bundleNames) { Bundle bundle = _bundleManager.getBundle(bundleId); List<Fragment> allFragments = bundle.getAllFragments(); if (allFragments.size() > LEVEL2_SIZE) { throw new IllegalStateException("DevBundleBuilder can only support " + LEVEL2_SIZE + " maximum fragments"); } buildVirtualBundles(devBundleManager, bundleId, allFragments); } return devBundleManager; } private void buildVirtualBundles(BundleManager bundleManager, String bundleId, List<Fragment> fragments) { long fragmentSize = fragments.size(); if (fragmentSize <= MAX_IMPORTS) { Bundle rootNode = new Bundle(bundleId); rootNode.getChildNodes().addAll(fragments); bundleManager.addBundle(rootNode); } if (fragmentSize > MAX_IMPORTS && fragmentSize <= LEVEL1_SIZE) { buildLevelOneBundles(bundleManager, bundleId, fragments); } if (fragmentSize > LEVEL1_SIZE && fragmentSize <= LEVEL2_SIZE) { buildLevelTwoBundles(bundleManager, bundleId, fragments); } } private void buildLevelTwoBundles(BundleManager bundleManager, String bundleId, List<Fragment> fragments) { Map<Integer, List<Fragment>> parentFragmentMap = split(fragments); Bundle rootNode = new Bundle(bundleId); for (Entry<Integer, List<Fragment>> parentEntry : parentFragmentMap.entrySet()) { String parentId = String.valueOf(parentEntry.getKey()); String parentName = buildBundleName(bundleId, parentId, null); Bundle parentBundle = new Bundle(parentName); Map<Integer, List<Fragment>> childFragmentMap = split(parentEntry.getValue()); for (Entry<Integer, List<Fragment>> childEntry : childFragmentMap.entrySet()) { String childName = buildBundleName(bundleId, parentId, String.valueOf(childEntry.getKey())); Bundle childBundle = new Bundle(childName); for (Fragment fragment : childEntry.getValue()) { childBundle.addChildNode(fragment); } parentBundle.addChildNode(childBundle); } rootNode.addChildNode(parentBundle); } bundleManager.addBundle(rootNode); } private void buildLevelOneBundles(BundleManager bundleManager, String bundleId, List<Fragment> fragments) { Map<Integer, List<Fragment>> fragmentMap = split(fragments); Bundle rootNode = new Bundle(bundleId); for (Entry<Integer, List<Fragment>> entry : fragmentMap.entrySet()) { String bundleName = buildBundleName(bundleId, String.valueOf(entry.getKey()), null); Bundle bundle = new Bundle(bundleName); List<Fragment> fragmentList = entry.getValue(); for (Fragment fragment : fragmentList) { bundle.addChildNode(fragment); } rootNode.addChildNode(bundle); } bundleManager.addBundle(rootNode); } private String buildBundleName(String bundleId, String parent, String child) { BundleType type = BundleType.getType(bundleId); StringBuilder buf = new StringBuilder(bundleId.substring(0, (bundleId.indexOf(type.getSuffix()) - 1))); if (parent != null) { buf.append("-"); buf.append(parent); } if (child != null) { buf.append("-"); buf.append(child); } buf.append(".").append(type.getSuffix()); return buf.toString(); } private Map<Integer, List<Fragment>> split(List<Fragment> fragments) { Map<Integer, List<Fragment>> result = new TreeMap<Integer, List<Fragment>>(); int bundleSize = (fragments.size() / MAX_IMPORTS); if (fragments.size() % MAX_IMPORTS != 0) { ++bundleSize; } int counter = 0; List<Fragment> current = new ArrayList<Fragment>(); int next = 1; for (Fragment fragment : fragments) { current.add(fragment); if (++counter % bundleSize == 0) { result.put(next++, new ArrayList<Fragment>(current)); current.clear(); } } if (!current.isEmpty()) { result.put(next, current); } return result; } }