List of usage examples for java.util SortedSet toArray
<T> T[] toArray(T[] a);
From source file:net.sf.fspdfs.chartthemes.spring.GenericChartTheme.java
protected void setPlotDrawingDefaults(Plot p, JRChartPlot jrPlot) { List defaultSeriesColors = (List) getDefaultValue(defaultChartPropertiesMap, ChartThemesConstants.SERIES_COLORS); Paint[] defaultPlotOutlinePaintSequence = getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_OUTLINE_PAINT_SEQUENCE) != null ? (Paint[]) getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_OUTLINE_PAINT_SEQUENCE) : DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE; Stroke[] defaultPlotStrokeSequence = getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_STROKE_SEQUENCE) != null ? (Stroke[]) getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_STROKE_SEQUENCE) : DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE; Stroke[] defaultPlotOutlineStrokeSequence = getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_OUTLINE_STROKE_SEQUENCE) != null ? (Stroke[]) getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_OUTLINE_STROKE_SEQUENCE) : DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE; Shape[] defaultPlotShapeSequence = getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_SHAPE_SEQUENCE) != null ? (Shape[]) getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_SHAPE_SEQUENCE) : DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE; // Set color series Paint[] colors = null;//from w ww. jav a2s .co m SortedSet seriesColors = jrPlot.getSeriesColors(); Paint[] colorSequence = null; if (seriesColors != null && seriesColors.size() > 0) { int seriesColorsSize = seriesColors.size(); colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + seriesColorsSize]; JRSeriesColor[] jrColorSequence = new JRSeriesColor[seriesColorsSize]; seriesColors.toArray(jrColorSequence); colorSequence = new Paint[seriesColorsSize]; for (int i = 0; i < seriesColorsSize; i++) { colorSequence[i] = jrColorSequence[i].getColor(); } populateSeriesColors(colors, colorSequence); } else if (defaultSeriesColors != null && defaultSeriesColors.size() > 0) { colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + defaultSeriesColors.size()]; colorSequence = new Paint[defaultSeriesColors.size()]; defaultSeriesColors.toArray(colorSequence); populateSeriesColors(colors, colorSequence); } else { colors = DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE; } p.setDrawingSupplier(new DefaultDrawingSupplier(colors, defaultPlotOutlinePaintSequence, defaultPlotStrokeSequence, defaultPlotOutlineStrokeSequence, defaultPlotShapeSequence)); }
From source file:net.sf.jasperreports.chartthemes.spring.GenericChartTheme.java
protected void setPlotDrawingDefaults(Plot p, JRChartPlot jrPlot) { @SuppressWarnings("unchecked") List<Paint> defaultSeriesColors = (List<Paint>) getDefaultValue(defaultChartPropertiesMap, ChartThemesConstants.SERIES_COLORS); Paint[] defaultPlotOutlinePaintSequence = getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_OUTLINE_PAINT_SEQUENCE) != null ? (Paint[]) getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_OUTLINE_PAINT_SEQUENCE) : DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE; Stroke[] defaultPlotStrokeSequence = getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_STROKE_SEQUENCE) != null ? (Stroke[]) getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_STROKE_SEQUENCE) : DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE; Stroke[] defaultPlotOutlineStrokeSequence = getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_OUTLINE_STROKE_SEQUENCE) != null ? (Stroke[]) getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_OUTLINE_STROKE_SEQUENCE) : DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE; Shape[] defaultPlotShapeSequence = getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_SHAPE_SEQUENCE) != null ? (Shape[]) getDefaultValue(defaultPlotPropertiesMap, ChartThemesConstants.PLOT_SHAPE_SEQUENCE) : DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE; // Set color series Paint[] colors = null;/*from w w w .ja va 2 s. c o m*/ SortedSet<JRSeriesColor> seriesColors = jrPlot.getSeriesColors(); Paint[] colorSequence = null; if (seriesColors != null && seriesColors.size() > 0) { int seriesColorsSize = seriesColors.size(); colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + seriesColorsSize]; JRSeriesColor[] jrColorSequence = new JRSeriesColor[seriesColorsSize]; seriesColors.toArray(jrColorSequence); colorSequence = new Paint[seriesColorsSize]; for (int i = 0; i < seriesColorsSize; i++) { colorSequence[i] = jrColorSequence[i].getColor(); } populateSeriesColors(colors, colorSequence); } else if (defaultSeriesColors != null && defaultSeriesColors.size() > 0) { colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + defaultSeriesColors.size()]; colorSequence = new Paint[defaultSeriesColors.size()]; defaultSeriesColors.toArray(colorSequence); populateSeriesColors(colors, colorSequence); } else { colors = DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE; } p.setDrawingSupplier(new DefaultDrawingSupplier(colors, defaultPlotOutlinePaintSequence, defaultPlotStrokeSequence, defaultPlotOutlineStrokeSequence, defaultPlotShapeSequence)); }
From source file:org.wrml.runtime.schema.generator.SchemaGenerator.java
/** * Generate a {@link JavaBytecodeClass} from the specified {@link Schema}. * <p/>//from ww w .j a v a 2s.c om * Like a *big* regex (regular expression), we can compile all of the * WRML schema metadata (as if it is a single *big* String input) into a * loaded Java class so that the rest of the WRML *runtime* can use * (Prototype-optimized) reflection to access WRML's type system. * * @param schema The Schema to represent as a Java class. * @return The Java class representation of the specified schema. */ public JavaBytecodeClass generateSchemaInterface(final Schema schema) { /* * Create the simple POJO that will return the transformation * information. By the end of this method, this will be full of Java * bytecode-oriented information gleaned from this method's schema * parameter. */ final JavaBytecodeClass javaBytecodeClass = new JavaBytecodeClass(); final JavaBytecodeAnnotation wrmlAnnotation = new JavaBytecodeAnnotation( SchemaGenerator.ANNOTATION_INTERNAL_NAME_WRML); wrmlAnnotation.setAttributeValue(AnnotationParameterName.uniqueName.name(), schema.getUniqueName().getFullName()); javaBytecodeClass.getAnnotations().add(wrmlAnnotation); final SortedSet<String> keySlotNameSet = new TreeSet<>(); /* * If the schema declares any key slots, note them with a * class-level annotation. */ final List<String> keySlotNames = schema.getKeySlotNames(); if (keySlotNames != null && keySlotNames.size() > 0) { keySlotNameSet.addAll(keySlotNames); } if (!keySlotNameSet.isEmpty()) { final String[] keySlotNamesArray = new String[keySlotNameSet.size()]; wrmlAnnotation.setAttributeValue(AnnotationParameterName.keySlotNames.name(), keySlotNameSet.toArray(keySlotNamesArray)); } /* * If the schema declares any comparable slots, note them with a * class-level annotation. */ final List<String> comparableSlotNames = schema.getComparableSlotNames(); if (comparableSlotNames != null && comparableSlotNames.size() > 0) { final String[] comparableSlotNamesArray = new String[comparableSlotNames.size()]; wrmlAnnotation.setAttributeValue(AnnotationParameterName.comparableSlotNames.name(), comparableSlotNames.toArray(comparableSlotNamesArray)); } wrmlAnnotation.setAttributeValue(AnnotationParameterName.titleSlotName.name(), schema.getTitleSlotName()); /* * In Java, all interfaces extend java.lang.Object, so this can * remain constant for Schema too. */ javaBytecodeClass.setSuperName(SchemaGenerator.OBJECT_INTERNAL_NAME); /* * Go from schema id (URI) to internal Java class name. This is a * simple matter of stripping the leading forward slash from the * URI's path. Internally (in the bytecode), Java's class names use * forward slash (/) instead of full stop dots (.). */ final URI schemaUri = schema.getUri(); final String interfaceInternalName = uriToInternalTypeName(schemaUri); // if (schema.getUniqueName() == null) // { // schema.setUniqueName(new UniqueName(schemaUri.getPath())); // } javaBytecodeClass.setInternalName(interfaceInternalName); /* * Add the class-level Description annotation to capture the * schema's description. */ final String schemaDescription = schema.getDescription(); if (schemaDescription != null && !schemaDescription.trim().isEmpty()) { final JavaBytecodeAnnotation schemaDescriptionAnnotation = new JavaBytecodeAnnotation( SchemaGenerator.ANNOTATION_INTERNAL_NAME_DESCRIPTION); schemaDescriptionAnnotation.setAttributeValue(AnnotationParameterName.value.name(), schemaDescription); javaBytecodeClass.getAnnotations().add(schemaDescriptionAnnotation); } String schemaTitle = schema.getTitle(); if (schemaTitle == null || schemaTitle.trim().isEmpty()) { schemaTitle = schema.getUniqueName().getLocalName(); } final JavaBytecodeAnnotation schemaTitleAnnotation = new JavaBytecodeAnnotation( SchemaGenerator.ANNOTATION_INTERNAL_NAME_TITLE); schemaTitleAnnotation.setAttributeValue(AnnotationParameterName.value.name(), schemaTitle); javaBytecodeClass.getAnnotations().add(schemaTitleAnnotation); final URI schemaThumbnailImageLocation = schema.getThumbnailLocation(); if (schemaThumbnailImageLocation != null) { final JavaBytecodeAnnotation schemaThumbnailImageAnnotation = new JavaBytecodeAnnotation( SchemaGenerator.ANNOTATION_INTERNAL_NAME_THUMBNAIL_IMAGE); schemaThumbnailImageAnnotation.setAttributeValue(AnnotationParameterName.value.name(), schemaThumbnailImageLocation.toString()); javaBytecodeClass.getAnnotations().add(schemaThumbnailImageAnnotation); } boolean isAggregate = false; /* * Turn the schema's base schema list into our Java class's base * (aka extended) interfaces. */ final List<URI> baseSchemaUris = schema.getBaseSchemaUris(); for (final URI baseSchemaUri : baseSchemaUris) { final String baseSchemaInternalName = uriToInternalTypeName(baseSchemaUri); javaBytecodeClass.getInterfaces().add(baseSchemaInternalName); if (!isAggregate && getSchemaLoader().getAggregateDocumentSchemaUri().equals(baseSchemaUri)) { isAggregate = true; final List<Slot> slots = schema.getSlots(); for (final Slot slot : slots) { final Value value = slot.getValue(); if (!(value instanceof LinkValue || value instanceof ModelValue || value instanceof MultiSelectValue)) { keySlotNameSet.add(slot.getName()); } } } } // Add the Model base interface javaBytecodeClass.getInterfaces().add(SchemaGenerator.MODEL_INTERFACE_INTERNAL_NAME); /* * Add the class-level Tags annotation to capture the schema's tags. */ final List<String> schemaTags = schema.getTags(); if (schemaTags != null && schemaTags.size() > 0) { final JavaBytecodeAnnotation tagsAnnotation = new JavaBytecodeAnnotation( SchemaGenerator.ANNOTATION_INTERNAL_NAME_TAGS); final String[] tagsArray = new String[schemaTags.size()]; tagsAnnotation.setAttributeValue(AnnotationParameterName.value.name(), schemaTags.toArray(tagsArray)); javaBytecodeClass.getAnnotations().add(tagsAnnotation); } final Long schemaVersion = schema.getVersion(); if (schemaVersion != null) { final JavaBytecodeAnnotation versionAnnotation = new JavaBytecodeAnnotation( SchemaGenerator.ANNOTATION_INTERNAL_NAME_VERSION); versionAnnotation.setAttributeValue(AnnotationParameterName.value.name(), schemaVersion); javaBytecodeClass.getAnnotations().add(versionAnnotation); } final Boolean maybeReadOnly = schema.isReadOnly(); if (maybeReadOnly != null && maybeReadOnly) { final JavaBytecodeAnnotation readOnlyAnnotation = new JavaBytecodeAnnotation( SchemaGenerator.ANNOTATION_INTERNAL_NAME_READ_ONLY); javaBytecodeClass.getAnnotations().add(readOnlyAnnotation); } /* * Generate the interface method signatures. */ generateSchemaInterfaceMethods(schema, javaBytecodeClass, isAggregate); // TODO: "Open slots" with signatures. Track the open slots via // the JavaBytecode types. // // TODO: The signature will need to be changed for generics: // Example: // // Java: public interface Test<T extends List<?>> extends List<T> // Class File: public abstract interface org.wrml.schema.Test // extends java.util.List // Signature: // <T::Ljava/util/List<*>;>Ljava/lang/Object;Ljava/util/List<TT;>; // javaBytecodeClass.setSignature(null); generateSchemaInterfaceBytecode(javaBytecodeClass); return javaBytecodeClass; }
From source file:net.sf.fspdfs.chartthemes.simple.SimpleChartTheme.java
protected Paint[] getPaintSequence(PlotSettings plotSettings, JRChartPlot jrPlot) { Paint[] colors = null;/*from w w w .j a v a2s.c om*/ SortedSet seriesColors = jrPlot.getSeriesColors(); Paint[] colorSequence = null; //The series gradient paint setting is considered first List themeSeriesPaintProvider = getChartThemeSettings().getPlotSettings() .getSeriesGradientPaintSequence() != null ? getChartThemeSettings().getPlotSettings().getSeriesGradientPaintSequence() : getChartThemeSettings().getPlotSettings().getSeriesColorSequence(); if (seriesColors != null && seriesColors.size() > 0) { int seriesColorsSize = seriesColors.size(); colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + seriesColorsSize]; JRSeriesColor[] jrColorSequence = new JRSeriesColor[seriesColorsSize]; seriesColors.toArray(jrColorSequence); colorSequence = new Paint[seriesColorsSize]; for (int i = 0; i < seriesColorsSize; i++) { colorSequence[i] = jrColorSequence[i].getColor(); } populateSeriesColors(colors, colorSequence); } else if (themeSeriesPaintProvider != null && !themeSeriesPaintProvider.isEmpty()) { colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + themeSeriesPaintProvider.size()]; colorSequence = new Paint[themeSeriesPaintProvider.size()]; List themeSeriesColors = new ArrayList(); for (int i = 0; i < themeSeriesPaintProvider.size(); i++) { themeSeriesColors.add(((PaintProvider) themeSeriesPaintProvider.get(i)).getPaint()); } themeSeriesColors.toArray(colorSequence); populateSeriesColors(colors, colorSequence); } else { colors = DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE; } return colors; }
From source file:net.sf.jasperreports.chartthemes.simple.SimpleChartTheme.java
protected Paint[] getPaintSequence(PlotSettings plotSettings, JRChartPlot jrPlot) { Paint[] colors = null;//from ww w.ja v a 2s. c o m SortedSet<JRSeriesColor> seriesColors = jrPlot.getSeriesColors(); Paint[] colorSequence = null; //The series gradient paint setting is considered first List<PaintProvider> themeSeriesPaintProvider = getChartThemeSettings().getPlotSettings() .getSeriesGradientPaintSequence() != null ? getChartThemeSettings().getPlotSettings().getSeriesGradientPaintSequence() : getChartThemeSettings().getPlotSettings().getSeriesColorSequence(); if (seriesColors != null && seriesColors.size() > 0) { int seriesColorsSize = seriesColors.size(); colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + seriesColorsSize]; JRSeriesColor[] jrColorSequence = new JRSeriesColor[seriesColorsSize]; seriesColors.toArray(jrColorSequence); colorSequence = new Paint[seriesColorsSize]; for (int i = 0; i < seriesColorsSize; i++) { colorSequence[i] = jrColorSequence[i].getColor(); } populateSeriesColors(colors, colorSequence); } else if (themeSeriesPaintProvider != null && !themeSeriesPaintProvider.isEmpty()) { colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + themeSeriesPaintProvider.size()]; colorSequence = new Paint[themeSeriesPaintProvider.size()]; List<Paint> themeSeriesColors = new ArrayList<Paint>(); for (int i = 0; i < themeSeriesPaintProvider.size(); i++) { themeSeriesColors.add(themeSeriesPaintProvider.get(i).getPaint()); } themeSeriesColors.toArray(colorSequence); populateSeriesColors(colors, colorSequence); } else { colors = DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE; } return colors; }
From source file:net.sf.jasperreports.engine.fill.DefaultChartTheme.java
/** * *//*ww w .j a v a 2 s .com*/ protected void configurePlot(Plot plot) { plot.setOutlinePaint(null); if (getPlot().getOwnBackcolor() == null)// in a way, plot backcolor inheritence from chart is useless { plot.setBackgroundPaint(null); } else { plot.setBackgroundPaint(getPlot().getBackcolor()); } float backgroundAlpha = getPlot().getBackgroundAlphaFloat() == null ? 1f : getPlot().getBackgroundAlphaFloat(); float foregroundAlpha = getPlot().getForegroundAlphaFloat() == null ? 1f : getPlot().getForegroundAlphaFloat(); plot.setBackgroundAlpha(backgroundAlpha); plot.setForegroundAlpha(foregroundAlpha); if (plot instanceof CategoryPlot) { // Handle rotation of the category labels. CategoryAxis axis = ((CategoryPlot) plot).getDomainAxis(); // it's OK to use deprecated method here; avoiding it means attempting cast operations double labelRotation = getLabelRotation(); if (labelRotation == 90) { axis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_90); } else if (labelRotation == -90) { axis.setCategoryLabelPositions(CategoryLabelPositions.UP_90); } else if (labelRotation < 0) { axis.setCategoryLabelPositions( CategoryLabelPositions.createUpRotationLabelPositions((-labelRotation / 180.0) * Math.PI)); } else if (labelRotation > 0) { axis.setCategoryLabelPositions( CategoryLabelPositions.createDownRotationLabelPositions((labelRotation / 180.0) * Math.PI)); } } // Set any color series SortedSet<JRSeriesColor> seriesColors = getPlot().getSeriesColors(); if (seriesColors != null && seriesColors.size() > 0) { if (seriesColors.size() == 1) { // Add the single color to the beginning of the color cycle, using all the default // colors. To replace the defaults you have to specify at least two colors. Paint[] colors = new Paint[DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length + 1]; colors[0] = seriesColors.first().getColor(); System.arraycopy(DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE, 0, colors, 1, DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE.length); plot.setDrawingSupplier( new DefaultDrawingSupplier(colors, DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE, DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE)); } else if (seriesColors.size() > 1) { // Set up a custom drawing supplier that cycles through the user's colors // instead of the default colors. Color[] colors = new Color[seriesColors.size()]; JRSeriesColor[] colorSequence = new JRSeriesColor[seriesColors.size()]; seriesColors.toArray(colorSequence); for (int i = 0; i < colorSequence.length; i++) { colors[i] = colorSequence[i].getColor(); } plot.setDrawingSupplier( new DefaultDrawingSupplier(colors, DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE, DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE)); } } }
From source file:net.sf.jasperreports.engine.util.JRApiWriter.java
/** * Writes out the contents of a series colors block for a chart. Assumes the caller * has already written the <code><seriesColors></code> tag. * * @param seriesColors the colors to write *///from w w w . j a v a2s . c om private void writeSeriesColors(SortedSet<JRSeriesColor> seriesColors, String parentName) { if (seriesColors == null || seriesColors.size() == 0) { return; } //FIXME why do we need an array? JRSeriesColor[] colors = seriesColors.toArray(new JRSeriesColor[seriesColors.size()]); for (int i = 0; i < colors.length; i++) { String seriesColorName = parentName + "SeriesColor" + i; write("JRBaseSeriesColor " + seriesColorName + " = new JRBaseSeriesColor(" + colors[i].getSeriesOrder() + ", {0});\n", colors[i].getColor()); write(parentName + ".addSeriesColor(" + seriesColorName + ");\n"); flush(); } }
From source file:org.apache.hadoop.hive.metastore.txn.TxnHandler.java
/** * Lock acquisition is meant to be fair, so every lock can only block on some lock with smaller * hl_lock_ext_id by only checking earlier locks. * * For any given SQL statment all locks required by it are grouped under single extLockId and are * granted all at once or all locks wait. * * This is expected to run at READ_COMMITTED. * * Note: this calls acquire() for (extLockId,intLockId) but extLockId is the same and we either take * all locks for given extLockId or none. Would be more efficient to update state on all locks * at once. Semantics are the same since this is all part of the same txn. * * If there is a concurrent commitTxn/rollbackTxn, those can only remove rows from HIVE_LOCKS. * If they happen to be for the same txnid, there will be a WW conflict (in MS DB), if different txnid, * checkLock() will in the worst case keep locks in Waiting state a little longer. *//*from w w w . j a v a 2s . c om*/ @RetrySemantics.SafeToRetry("See @SafeToRetry") private LockResponse checkLock(Connection dbConn, long extLockId) throws NoSuchLockException, NoSuchTxnException, TxnAbortedException, MetaException, SQLException { TxnStore.MutexAPI.LockHandle handle = null; Statement stmt = null; ResultSet rs = null; LockResponse response = new LockResponse(); /** * todo: Longer term we should pass this from client somehow - this would be an optimization; once * that is in place make sure to build and test "writeSet" below using OperationType not LockType * With Static Partitions we assume that the query modifies exactly the partitions it locked. (not entirely * realistic since Update/Delete may have some predicate that filters out all records out of * some partition(s), but plausible). For DP, we acquire locks very wide (all known partitions), * but for most queries only a fraction will actually be updated. #addDynamicPartitions() tells * us exactly which ones were written to. Thus using this trick to kill a query early for * DP queries may be too restrictive. */ boolean isPartOfDynamicPartitionInsert = true; try { /** * checkLock() must be mutexed against any other checkLock to make sure 2 conflicting locks * are not granted by parallel checkLock() calls. */ handle = getMutexAPI().acquireLock(MUTEX_KEY.CheckLock.name()); List<LockInfo> locksBeingChecked = getLockInfoFromLockId(dbConn, extLockId);//being acquired now response.setLockid(extLockId); LOG.debug("checkLock(): Setting savepoint. extLockId=" + JavaUtils.lockIdToString(extLockId)); Savepoint save = dbConn.setSavepoint(); StringBuilder query = new StringBuilder( "select hl_lock_ext_id, " + "hl_lock_int_id, hl_db, hl_table, hl_partition, hl_lock_state, " + "hl_lock_type, hl_txnid from HIVE_LOCKS where hl_db in ("); Set<String> strings = new HashSet<String>(locksBeingChecked.size()); //This the set of entities that the statement represented by extLockId wants to update List<LockInfo> writeSet = new ArrayList<>(); for (LockInfo info : locksBeingChecked) { strings.add(info.db); if (!isPartOfDynamicPartitionInsert && info.type == LockType.SHARED_WRITE) { writeSet.add(info); } } if (!writeSet.isEmpty()) { if (writeSet.get(0).txnId == 0) { //Write operation always start a txn throw new IllegalStateException( "Found Write lock for " + JavaUtils.lockIdToString(extLockId) + " but no txnid"); } stmt = dbConn.createStatement(); StringBuilder sb = new StringBuilder( " ws_database, ws_table, ws_partition, " + "ws_txnid, ws_commit_id " + "from WRITE_SET where ws_commit_id >= " + writeSet.get(0).txnId + " and (");//see commitTxn() for more info on this inequality for (LockInfo info : writeSet) { sb.append("(ws_database = ").append(quoteString(info.db)).append(" and ws_table = ") .append(quoteString(info.table)).append(" and ws_partition ") .append(info.partition == null ? "is null" : "= " + quoteString(info.partition)) .append(") or "); } sb.setLength(sb.length() - 4);//nuke trailing " or " sb.append(")"); //1 row is sufficient to know we have to kill the query rs = stmt.executeQuery(sqlGenerator.addLimitClause(1, sb.toString())); if (rs.next()) { /** * if here, it means we found an already committed txn which overlaps with the current one and * it updated the same resource the current txn wants to update. By First-committer-wins * rule, current txn will not be allowed to commit so may as well kill it now; This is just an * optimization to prevent wasting cluster resources to run a query which is known to be DOA. * {@link #commitTxn(CommitTxnRequest)} has the primary responsibility to ensure this. * checkLock() runs at READ_COMMITTED so you could have another (Hive) txn running commitTxn() * in parallel and thus writing to WRITE_SET. commitTxn() logic is properly mutexed to ensure * that we don't "miss" any WW conflicts. We could've mutexed the checkLock() and commitTxn() * as well but this reduces concurrency for very little gain. * Note that update/delete (which runs as dynamic partition insert) acquires a lock on the table, * but WRITE_SET has entries for actual partitions updated. Thus this optimization will "miss" * the WW conflict but it will be caught in commitTxn() where actual partitions written are known. * This is OK since we want 2 concurrent updates that update different sets of partitions to both commit. */ String resourceName = rs.getString(1) + '/' + rs.getString(2); String partName = rs.getString(3); if (partName != null) { resourceName += '/' + partName; } String msg = "Aborting " + JavaUtils.txnIdToString(writeSet.get(0).txnId) + " since a concurrent committed transaction [" + JavaUtils.txnIdToString(rs.getLong(4)) + "," + rs.getLong(5) + "] has already updated resouce '" + resourceName + "'"; LOG.info(msg); if (abortTxns(dbConn, Collections.singletonList(writeSet.get(0).txnId), true) != 1) { throw new IllegalStateException(msg + " FAILED!"); } dbConn.commit(); throw new TxnAbortedException(msg); } close(rs, stmt, null); } boolean first = true; for (String s : strings) { if (first) first = false; else query.append(", "); query.append('\''); query.append(s); query.append('\''); } query.append(")"); // If any of the table requests are null, then I need to pull all the // table locks for this db. boolean sawNull = false; strings.clear(); for (LockInfo info : locksBeingChecked) { if (info.table == null) { sawNull = true; break; } else { strings.add(info.table); } } if (!sawNull) { query.append(" and (hl_table is null or hl_table in("); first = true; for (String s : strings) { if (first) first = false; else query.append(", "); query.append('\''); query.append(s); query.append('\''); } query.append("))"); // If any of the partition requests are null, then I need to pull all // partition locks for this table. sawNull = false; strings.clear(); for (LockInfo info : locksBeingChecked) { if (info.partition == null) { sawNull = true; break; } else { strings.add(info.partition); } } if (!sawNull) { query.append(" and (hl_partition is null or hl_partition in("); first = true; for (String s : strings) { if (first) first = false; else query.append(", "); query.append('\''); query.append(s); query.append('\''); } query.append("))"); } } query.append(" and hl_lock_ext_id <= ").append(extLockId); LOG.debug("Going to execute query <" + query.toString() + ">"); stmt = dbConn.createStatement(); rs = stmt.executeQuery(query.toString()); SortedSet<LockInfo> lockSet = new TreeSet<LockInfo>(new LockInfoComparator()); while (rs.next()) { lockSet.add(new LockInfo(rs)); } // Turn the tree set into an array so we can move back and forth easily // in it. LockInfo[] locks = lockSet.toArray(new LockInfo[lockSet.size()]); if (LOG.isTraceEnabled()) { LOG.trace("Locks to check(full): "); for (LockInfo info : locks) { LOG.trace(" " + info); } } for (LockInfo info : locksBeingChecked) { // Find the lock record we're checking int index = -1; for (int i = 0; i < locks.length; i++) { if (locks[i].equals(info)) { index = i; break; } } // If we didn't find the lock, then it must not be in the table if (index == -1) { LOG.debug("Going to rollback"); dbConn.rollback(); throw new MetaException( "How did we get here, we heartbeated our lock before we started! ( " + info + ")"); } // If we've found it and it's already been marked acquired, // then just look at the other locks. if (locks[index].state == LockState.ACQUIRED) { /**this is what makes this method @SafeToRetry*/ continue; } // Look at everything in front of this lock to see if it should block // it or not. boolean acquired = false; for (int i = index - 1; i >= 0; i--) { // Check if we're operating on the same database, if not, move on if (!locks[index].db.equals(locks[i].db)) { continue; } // If table is null on either of these, then they are claiming to // lock the whole database and we need to check it. Otherwise, // check if they are operating on the same table, if not, move on. if (locks[index].table != null && locks[i].table != null && !locks[index].table.equals(locks[i].table)) { continue; } // If partition is null on either of these, then they are claiming to // lock the whole table and we need to check it. Otherwise, // check if they are operating on the same partition, if not, move on. if (locks[index].partition != null && locks[i].partition != null && !locks[index].partition.equals(locks[i].partition)) { continue; } // We've found something that matches what we're trying to lock, // so figure out if we can lock it too. LockAction lockAction = jumpTable.get(locks[index].type).get(locks[i].type).get(locks[i].state); LOG.debug("desired Lock: " + info + " checked Lock: " + locks[i] + " action: " + lockAction); switch (lockAction) { case WAIT: if (!ignoreConflict(info, locks[i])) { /*we acquire all locks for a given query atomically; if 1 blocks, all go into (remain) in * Waiting state. wait() will undo any 'acquire()' which may have happened as part of * this (metastore db) transaction and then we record which lock blocked the lock * we were testing ('info').*/ wait(dbConn, save); String sqlText = "update HIVE_LOCKS" + " set HL_BLOCKEDBY_EXT_ID=" + locks[i].extLockId + ", HL_BLOCKEDBY_INT_ID=" + locks[i].intLockId + " where HL_LOCK_EXT_ID=" + info.extLockId + " and HL_LOCK_INT_ID=" + info.intLockId; LOG.debug("Executing sql: " + sqlText); int updCnt = stmt.executeUpdate(sqlText); if (updCnt != 1) { shouldNeverHappen(info.txnId, info.extLockId, info.intLockId); } LOG.debug("Going to commit"); dbConn.commit(); response.setState(LockState.WAITING); LOG.debug("Lock(" + info + ") waiting for Lock(" + locks[i] + ")"); return response; } //fall through to ACQUIRE case ACQUIRE: acquire(dbConn, stmt, extLockId, info); acquired = true; break; case KEEP_LOOKING: continue; } if (acquired) break; // We've acquired this lock component, // so get out of the loop and look at the next component. } // If we've arrived here and we have not already acquired, it means there's nothing in the // way of the lock, so acquire the lock. if (!acquired) acquire(dbConn, stmt, extLockId, info); } // We acquired all of the locks, so commit and return acquired. LOG.debug("Going to commit"); dbConn.commit(); response.setState(LockState.ACQUIRED); } finally { close(rs, stmt, null); if (handle != null) { handle.releaseLocks(); } } return response; }
From source file:uk.ac.liverpool.thumbnails.PDFService.java
@Override public FontInformation[] extractFontList(URI u, File fff) throws MalformedURLException, IOException { SortedSet<FontInformation> ret = new TreeSet<FontInformation>(); PDDocument document = getPages(u, fff); List pages = document.getDocumentCatalog().getAllPages(); int i = 0;//ww w .j a va 2 s. c om // The code down here is easier as it gets all the fonts used in the document. Still, this would inlcude unused fonts, so we get the fonts page by page and add them to a Hash table. for (COSObject c : document.getDocument().getObjectsByType(COSName.FONT)) { if (c == null || !(c.getObject() instanceof COSDictionary)) continue; //System.out.println(c.getObject()); COSDictionary fontDictionary = (COSDictionary) c.getObject(); // System.out.println(dic.getNameAsString(COSName.BASE_FONT)); // } // } // int pagen = document.getNumberOfPages(); // i=0; // for (int p=0;p<pagen;p++){ // PDPage page = (PDPage)pages.get(p); // PDResources res = page.findResources(); // //for each page resources // if (res==null) continue; // // get the font dictionary // COSDictionary fonts = (COSDictionary) res.getCOSDictionary().getDictionaryObject( COSName.FONT ); // for( COSName fontName : fonts.keySet() ) { // COSObject font = (COSObject) fonts.getItem( fontName ); // // if the font has already been visited we ingore it // long objectId = font.getObjectNumber().longValue(); // if (ret.get(objectId)!=null) // continue; // if( font==null || ! (font.getObject() instanceof COSDictionary) ) // continue; // COSDictionary fontDictionary = (COSDictionary)font.getObject(); // Type MUSt be font if (!fontDictionary.getNameAsString(COSName.TYPE).equals("Font")) continue; // get the variables FontInformation fi = new FontInformation(); fi.fontType = fontDictionary.getNameAsString(COSName.SUBTYPE); String baseFont = fontDictionary.getNameAsString(COSName.BASE_FONT); if (baseFont == null) continue; if (Arrays.binarySearch(standard14, baseFont) >= 0) continue; COSDictionary fontDescriptor = (COSDictionary) fontDictionary.getDictionaryObject(COSName.FONT_DESC); COSBase enc = fontDictionary.getItem(COSName.ENCODING); COSBase uni = fontDictionary.getItem(COSName.TO_UNICODE); int firstChar = fontDictionary.getInt(COSName.FIRST_CHAR); int lastChar = fontDictionary.getInt(COSName.LAST_CHAR); String encoding; boolean toUnicode = uni != null; if (enc == null) { encoding = "standard14"; } if (enc instanceof COSString) { encoding = ((COSString) enc).getString(); } else { encoding = "table"; } fi.isSubset = false; boolean t = true; // Type one and TT can have subsets defineing the basename see 5.5.3 pdfref 1.6 // if (fi.fontType.lastIndexOf(COSName.TYPE1.getName())!=-1 || fi.fontType.equals(COSName.TRUE_TYPE.getName()) ) if (baseFont != null) { if (baseFont.length() > 6) { for (int k = 0; k < 6; k++) if (!Character.isUpperCase(baseFont.charAt(k))) t = false; if (baseFont.charAt(6) != '+') t = false; } else t = false; fi.isSubset = t; if (fi.isSubset) baseFont = baseFont.substring(7); } fi.fontFlags = 0; if (fi.fontType.equals(COSName.TYPE0) || fi.fontType.equals(COSName.TYPE3)) fi.isEmbedded = true; if (fontDescriptor != null) { // in Type1 charset indicates font is subsetted if (fontDescriptor.getItem(COSName.CHAR_SET) != null) fi.isSubset = true; if (fontDescriptor.getItem(COSName.FONT_FILE) != null || fontDescriptor.getItem(COSName.FONT_FILE3) != null || fontDescriptor.getItem(COSName.FONT_FILE2) != null) fi.isEmbedded = true; fi.fontFlags = fontDescriptor.getInt(COSName.getPDFName("Flags")); fi.fontFamily = fontDescriptor.getString(COSName.FONT_FAMILY); fi.fontStretch = fontDescriptor.getString(COSName.FONT_STRETCH); } fi.charset = encoding; fi.fontName = baseFont; fi.isToUnicode = toUnicode; ret.add(fi); } // for all fonts // } // for all pages Iterator<FontInformation> it = ret.iterator(); FontInformation prev = null; LinkedList<FontInformation> toDelete = new LinkedList<FontInformation>(); while (it.hasNext()) { FontInformation current = it.next(); if (prev != null && prev.fontName.equals(current.fontName) && prev.fontType.startsWith("CIDFontType")) toDelete.add(current); prev = current; } ret.removeAll(toDelete); FontInformation[] retArray = ret.toArray(new FontInformation[0]); return retArray; }
From source file:com.android.mms.transaction.MessagingNotification.java
/** * updateNotification is *the* main function for building the actual notification handed to * the NotificationManager// ww w. ja va 2 s .c o m * @param context * @param newThreadId the new thread id * @param uniqueThreadCount * @param notificationSet the set of notifications to display */ private static void updateNotification(Context context, long newThreadId, int uniqueThreadCount, SortedSet<NotificationInfo> notificationSet) { boolean isNew = newThreadId != THREAD_NONE; CMConversationSettings conversationSettings = CMConversationSettings.getOrNew(context, newThreadId); // If the user has turned off notifications in settings, don't do any notifying. if ((isNew && !conversationSettings.getNotificationEnabled()) || !MessagingPreferenceActivity.getNotificationEnabled(context)) { if (DEBUG) { Log.d(TAG, "updateNotification: notifications turned off in prefs, bailing"); } return; } // Figure out what we've got -- whether all sms's, mms's, or a mixture of both. final int messageCount = notificationSet.size(); NotificationInfo mostRecentNotification = notificationSet.first(); final NotificationCompat.Builder noti = new NotificationCompat.Builder(context) .setWhen(mostRecentNotification.mTimeMillis); if (isNew) { noti.setTicker(mostRecentNotification.mTicker); } // If we have more than one unique thread, change the title (which would // normally be the contact who sent the message) to a generic one that // makes sense for multiple senders, and change the Intent to take the // user to the conversation list instead of the specific thread. // Cases: // 1) single message from single thread - intent goes to ComposeMessageActivity // 2) multiple messages from single thread - intent goes to ComposeMessageActivity // 3) messages from multiple threads - intent goes to ConversationList final Resources res = context.getResources(); String title = null; Bitmap avatar = null; PendingIntent pendingIntent = null; boolean isMultiNewMessages = MessageUtils.isMailboxMode() ? messageCount > 1 : uniqueThreadCount > 1; if (isMultiNewMessages) { // messages from multiple threads Intent mainActivityIntent = getMultiThreadsViewIntent(context); pendingIntent = PendingIntent.getActivity(context, 0, mainActivityIntent, PendingIntent.FLAG_UPDATE_CURRENT); title = context.getString(R.string.message_count_notification, messageCount); } else { // same thread, single or multiple messages title = mostRecentNotification.mTitle; avatar = mostRecentNotification.mSender.getAvatar(context); noti.setSubText(mostRecentNotification.mSimName); // no-op in single SIM case if (avatar != null) { // Show the sender's avatar as the big icon. Contact bitmaps are 96x96 so we // have to scale 'em up to 128x128 to fill the whole notification large icon. final int idealIconHeight = res .getDimensionPixelSize(android.R.dimen.notification_large_icon_height); final int idealIconWidth = res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width); noti.setLargeIcon(BitmapUtil.getRoundedBitmap(avatar, idealIconWidth, idealIconHeight)); } pendingIntent = PendingIntent.getActivity(context, 0, mostRecentNotification.mClickIntent, PendingIntent.FLAG_UPDATE_CURRENT); } // Always have to set the small icon or the notification is ignored noti.setSmallIcon(R.drawable.stat_notify_sms); NotificationManagerCompat nm = NotificationManagerCompat.from(context); // Update the notification. noti.setContentTitle(title).setContentIntent(pendingIntent) .setColor(context.getResources().getColor(R.color.mms_theme_color)) .setCategory(Notification.CATEGORY_MESSAGE).setPriority(Notification.PRIORITY_DEFAULT); // TODO: set based on contact coming // from a favorite. // Tag notification with all senders. for (NotificationInfo info : notificationSet) { Uri peopleReferenceUri = info.mSender.getPeopleReferenceUri(); if (peopleReferenceUri != null) { noti.addPerson(peopleReferenceUri.toString()); } } int defaults = 0; if (isNew) { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); if (conversationSettings.getVibrateEnabled()) { String pattern = conversationSettings.getVibratePattern(); if (!TextUtils.isEmpty(pattern)) { noti.setVibrate(parseVibratePattern(pattern)); } else { defaults |= Notification.DEFAULT_VIBRATE; } } String ringtoneStr = conversationSettings.getNotificationTone(); noti.setSound(TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr)); Log.d(TAG, "updateNotification: new message, adding sound to the notification"); } defaults |= Notification.DEFAULT_LIGHTS; noti.setDefaults(defaults); // set up delete intent noti.setDeleteIntent(PendingIntent.getBroadcast(context, 0, sNotificationOnDeleteIntent, 0)); // See if QuickMessage pop-up support is enabled in preferences boolean qmPopupEnabled = MessagingPreferenceActivity.getQuickMessageEnabled(context); // Set up the QuickMessage intent Intent qmIntent = null; if (mostRecentNotification.mIsSms) { // QuickMessage support is only for SMS qmIntent = new Intent(); qmIntent.setClass(context, QuickMessagePopup.class); qmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); qmIntent.putExtra(QuickMessagePopup.SMS_FROM_NAME_EXTRA, mostRecentNotification.mSender.getName()); qmIntent.putExtra(QuickMessagePopup.SMS_FROM_NUMBER_EXTRA, mostRecentNotification.mSender.getNumber()); qmIntent.putExtra(QuickMessagePopup.SMS_NOTIFICATION_OBJECT_EXTRA, mostRecentNotification); } // Start getting the notification ready final Notification notification; //Create a WearableExtender to add actions too WearableExtender wearableExtender = new WearableExtender(); if (messageCount == 1 || uniqueThreadCount == 1) { // Add the Quick Reply action only if the pop-up won't be shown already if (!qmPopupEnabled && qmIntent != null) { // This is a QR, we should show the keyboard when the user taps to reply qmIntent.putExtra(QuickMessagePopup.QR_SHOW_KEYBOARD_EXTRA, true); // Create the pending intent and add it to the notification CharSequence qmText = context.getText(R.string.menu_reply); PendingIntent qmPendingIntent = PendingIntent.getActivity(context, 0, qmIntent, PendingIntent.FLAG_UPDATE_CURRENT); noti.addAction(R.drawable.ic_reply, qmText, qmPendingIntent); //Wearable noti.extend(wearableExtender.addAction( new NotificationCompat.Action.Builder(R.drawable.ic_reply, qmText, qmPendingIntent) .build())); } // Add the 'Mark as read' action CharSequence markReadText = context.getText(R.string.qm_mark_read); Intent mrIntent = new Intent(); mrIntent.setClass(context, QmMarkRead.class); mrIntent.putExtra(QmMarkRead.SMS_THREAD_ID, mostRecentNotification.mThreadId); PendingIntent mrPendingIntent = PendingIntent.getBroadcast(context, 0, mrIntent, PendingIntent.FLAG_UPDATE_CURRENT); noti.addAction(R.drawable.ic_mark_read, markReadText, mrPendingIntent); // Add the Call action CharSequence callText = context.getText(R.string.menu_call); Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setData(Uri.parse("tel:" + mostRecentNotification.mSender.getNumber())); PendingIntent callPendingIntent = PendingIntent.getActivity(context, 0, callIntent, PendingIntent.FLAG_UPDATE_CURRENT); noti.addAction(R.drawable.ic_menu_call, callText, callPendingIntent); //Wearable noti.extend(wearableExtender.addAction( new NotificationCompat.Action.Builder(R.drawable.ic_menu_call, callText, callPendingIntent) .build())); //Set up remote input String replyLabel = context.getString(R.string.qm_wear_voice_reply); RemoteInput remoteInput = new RemoteInput.Builder(QuickMessageWear.EXTRA_VOICE_REPLY) .setLabel(replyLabel).build(); //Set up pending intent for voice reply Intent voiceReplyIntent = new Intent(context, QuickMessageWear.class); voiceReplyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); voiceReplyIntent.putExtra(QuickMessageWear.SMS_CONATCT, mostRecentNotification.mSender.getName()); voiceReplyIntent.putExtra(QuickMessageWear.SMS_SENDER, mostRecentNotification.mSender.getNumber()); voiceReplyIntent.putExtra(QuickMessageWear.SMS_THEAD_ID, mostRecentNotification.mThreadId); PendingIntent voiceReplyPendingIntent = PendingIntent.getActivity(context, 0, voiceReplyIntent, PendingIntent.FLAG_UPDATE_CURRENT); //Wearable voice reply action NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply, context.getString(R.string.qm_wear_reply_by_voice), voiceReplyPendingIntent) .addRemoteInput(remoteInput).build(); noti.extend(wearableExtender.addAction(action)); } if (messageCount == 1) { // We've got a single message // This sets the text for the collapsed form: noti.setContentText(mostRecentNotification.formatBigMessage(context)); if (mostRecentNotification.mAttachmentBitmap != null) { // The message has a picture, show that NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(noti) .bigPicture(mostRecentNotification.mAttachmentBitmap) .setSummaryText(mostRecentNotification.formatPictureMessage(context)); notification = noti.setStyle(bigPictureStyle).build(); } else { // Show a single notification -- big style with the text of the whole message NotificationCompat.BigTextStyle bigTextStyle1 = new NotificationCompat.BigTextStyle(noti) .bigText(mostRecentNotification.formatBigMessage(context)); notification = noti.setStyle(bigTextStyle1).build(); } if (DEBUG) { Log.d(TAG, "updateNotification: single message notification"); } } else { // We've got multiple messages if (!isMultiNewMessages) { // We've got multiple messages for the same thread. // Starting with the oldest new message, display the full text of each message. // Begin a line for each subsequent message. SpannableStringBuilder buf = new SpannableStringBuilder(); NotificationInfo infos[] = notificationSet.toArray(new NotificationInfo[messageCount]); int len = infos.length; for (int i = len - 1; i >= 0; i--) { NotificationInfo info = infos[i]; buf.append(info.formatBigMessage(context)); if (i != 0) { buf.append('\n'); } } noti.setContentText(context.getString(R.string.message_count_notification, messageCount)); // Show a single notification -- big style with the text of all the messages NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle(); bigTextStyle.bigText(buf) // Forcibly show the last line, with the app's smallIcon in it, if we // kicked the smallIcon out with an avatar bitmap .setSummaryText((avatar == null) ? null : " "); notification = noti.setStyle(bigTextStyle).build(); if (DEBUG) { Log.d(TAG, "updateNotification: multi messages for single thread"); } } else { // Build a set of the most recent notification per threadId. HashSet<Long> uniqueThreads = new HashSet<Long>(messageCount); ArrayList<NotificationInfo> mostRecentNotifPerThread = new ArrayList<NotificationInfo>(); Iterator<NotificationInfo> notifications = notificationSet.iterator(); while (notifications.hasNext()) { NotificationInfo notificationInfo = notifications.next(); if (!uniqueThreads.contains(notificationInfo.mThreadId)) { uniqueThreads.add(notificationInfo.mThreadId); mostRecentNotifPerThread.add(notificationInfo); } } // When collapsed, show all the senders like this: // Fred Flinstone, Barry Manilow, Pete... noti.setContentText(formatSenders(context, mostRecentNotifPerThread)); NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(noti); // We have to set the summary text to non-empty so the content text doesn't show // up when expanded. inboxStyle.setSummaryText(" "); // At this point we've got multiple messages in multiple threads. We only // want to show the most recent message per thread, which are in // mostRecentNotifPerThread. int uniqueThreadMessageCount = mostRecentNotifPerThread.size(); int maxMessages = Math.min(MAX_MESSAGES_TO_SHOW, uniqueThreadMessageCount); for (int i = 0; i < maxMessages; i++) { NotificationInfo info = mostRecentNotifPerThread.get(i); inboxStyle.addLine(info.formatInboxMessage(context)); } notification = inboxStyle.build(); uniqueThreads.clear(); mostRecentNotifPerThread.clear(); if (DEBUG) { Log.d(TAG, "updateNotification: multi messages," + " showing inboxStyle notification"); } } } notifyUserIfFullScreen(context, title); nm.notify(NOTIFICATION_ID, notification); // Trigger the QuickMessage pop-up activity if enabled // But don't show the QuickMessage if the user is in a call or the phone is ringing if (qmPopupEnabled && qmIntent != null) { TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE && !ConversationList.mIsRunning && !ComposeMessageActivity.mIsRunning) { context.startActivity(qmIntent); } } }